|
Hi! I've been trying to change values the whole day and bumped into an exception I can't handle with. So my strategy was creating two files: output.txt and array.txt. The first one was filled with changed values and the second with information regarding the rastr position of the original image: StripsInImage, height, rowsPerStrip, width and tmpBytes - a massive of Strips positions. This part was embedded into ReadPixelData Method in IFD Class:
void ReadPixelData()
{
double stripsPerImage = Math.Floor((height + rowsPerStrip - 1.0) / rowsPerStrip);
uint lastStripNumberOfRows = (uint)(height - rowsPerStrip * ((int)(stripsPerImage) - 1));
uint offset;
ushort pixVal;
int StripsInImage = (int)stripsPerImage;
byte[] tmpBytes;
if (samplesPerPixel == 1)
{
if (bitsPerSample == 16)
{
Pixels16.Clear();
for (int i = 0; i < stripsPerImage - 1; ++i)
{
offset = stripOffsets[i];
bReader.BaseStream.Seek(offset, SeekOrigin.Begin);
tmpBytes = bReader.ReadBytes(StripsInImage);
bReader.BaseStream.Seek(offset, SeekOrigin.Begin);
bWriter.Write(StripsInImage);
bWriter.Write(height);
bWriter.Write(rowsPerStrip);
bWriter.Write(width);
bWriter.Write(tmpBytes);
for (int j = 0; j < rowsPerStrip * width; ++j)
{
pixVal = bReader.ReadUInt16();
Pixels16.Add(pixVal);
}
}
offset = stripOffsets[stripOffsets.Count - 1];
bReader.BaseStream.Seek(offset, SeekOrigin.Begin);
bWriter.Close();
for (int j = 0; j < lastStripNumberOfRows * width; ++j)
{
pixVal = bReader.ReadUInt16();
Pixels16.Add(pixVal);
}
pixVal = 5;
}
else
{
}
}
else
{
}
}
and bWriter:
public IFD(BinaryReader br, TiffDecoder tiff)
{
bWriter = new BinaryWriter(new FileStream("array.txt", FileMode.Create));
bReader = br;
numberOfEntries = 0;
tiffDec = tiff;
listEntries = new List<DirectoryEntry>();
stripOffsets = new List<uint>();
stripByteCounts = new List<uint>();
Pixels16 = new List<ushort>();
}
The output.txt is in Form1.cs
public void WriteToFile()
{
bw = new BinaryWriter(new FileStream("output.txt", FileMode.Create));
for (int i = 0; i < pixels16.Count; ++i)
{
bw.Write(pixels16[i]);
}
bw.Close();
}
And the location of it is in Process Button Click EventHandler
private void process_btn_Click(object sender, EventArgs e)
{
int Iter = Convert.ToInt32(TextStep.Text);
double D0 = Convert.ToDouble(textBoxD0.Text);
double lambda = Convert.ToDouble(textBoxLambda.Text);
if (rbtnLD.Checked)
{
Algorithm a = new Algorithm(pixels16, width, height);
a.Set_D0_h1_h2_t_lambda_Iter(D0, 1, 1, 1, lambda, Iter);
a.Set_sigma(0.5);
a.LinDif(ref pixels16, ref this.progressBar1);
CreateBitmap();
Invalidate();
}
else if(rbtnND.Checked)
{
Algorithm a = new Algorithm(pixels16, width, height);
a.Set_D0_h1_h2_t_lambda_Iter(D0, 1, 1, 1, lambda, Iter);
a.Set_sigma(0.5);
a.PeronaMalik(ref pixels16, ref this.progressBar1);
CreateBitmap();
Invalidate();
}
WriteToFile();
WriteCopy();
}
The code:
public void WriteCopy()
{
int StripsInImage;
uint Height;
uint rowsPerStrip;
uint Width;
byte[] tmpBytes;
ushort pixVal;
using (FileStream OreadStream = File.OpenRead("output.txt"))
using (FileStream AreadStream = File.OpenRead("array.txt"))
using (FileStream writeStream = File.OpenWrite("copy.tif"))
{
BinaryWriter writer = new BinaryWriter(writeStream);
BinaryReader Areader = new BinaryReader(AreadStream);
BinaryReader Oreader = new BinaryReader(OreadStream);
Oreader.BaseStream.Seek(0, SeekOrigin.Begin);
StripsInImage = Areader.ReadUInt16();
Height = Areader.ReadUInt16();
rowsPerStrip = Areader.ReadUInt16();
Width = Areader.ReadUInt16();
tmpBytes = Areader.ReadBytes(StripsInImage);
for (int i = 0; i < StripsInImage - 1; ++i)
{
writer.BaseStream.Seek(tmpBytes[i], SeekOrigin.Begin);
for (int j = 0; j < rowsPerStrip * width; ++j)
{
pixVal = Oreader.ReadUInt16();
writer.Write(pixVal);
}
}
}
}
The Exception:
System.IO.EndOfStreamException
Additional Information: Reading after the end of a stream is impossible.
I don't understand Why it's The End of the Stream?
Sorry for long details!
Will be very grateful for any comments and corrections!
Thank you in advance!
|
|
|
|
|
Hi, this will take some time for me to analyze, since I am busy with other things till Tuesday next.
Meanwhile, I suggest you use the Debugger which comes with Visual Studio, especially the Watch and QuickWatch to inspect the values contained in the variables; and then try to see where things need correction. All the best in this.
|
|
|
|
|
|
Hi there! A new question in new year)
I've been looking into the Threading and bumped into some real pain in the neck, I have read some information in Shildt and decided to use TPL library since it's the most effective way to do multithreading, so I started with embedding Using System.Threading.Tasks in the program and it messaged me that this namespace doesn't exist in System.Threading, so I googled and found out that it might be .Net Framework problem. I checked to make sure I get the Latest version so it proved to be true, but the most mysterious thing is when I create a new Windows Form Project, this namespace is already inserted, but in your project it isn't, maybe it has smth to do with the fact that the program was written in 2008 and used an earlier version of .Net Framework? and What to do if it's true? rewrite the program or there is another way?
Thanks in advance!
|
|
|
|
|
1. See whether this would work:
- Create a new WinForms Project,
- Copy all necessary code from the existing project, method-wise, and then just build and run.
This should work.
2. Or also, open the existing project into the new version of Visual Studio, and allow it to convert to the latest version. From what I know, Visual Studio prompts the user while loading, for converting to the new version.
3. This article[^] has a converter to 2010. See whether this would help.
|
|
|
|
|
Hello! Your program works perfectly well with Raw Data! But it doesn't display 16 bit TIFF images i have, you mentioned that it can be extended to have this capability, could you please give me a hint how it can be done?
|
|
|
|
|
Good to know that it worked well for raw images.
Regarding TIFF files, you need to read in the header information, to get the image details - width, height, bits per pixel, starting location of the pixel buffer, etc. (all embedded within the TIFF header).
There are two sources:
1. Book by Dwayne Phillips, available online for free, along with C code[^]. I feel this would be sufficient.
2. If the above is not enough, go to the TIFF 6 spec[^].
Hope this helps. Please get back for any further clarifications.
|
|
|
|
|
Thank you very much for reply, I certainly will!
modified 14-Nov-15 13:23pm.
|
|
|
|
|
Hi again! thank you for the book by the way! Actually i read a similar one some time ago and got the hang of an idea of storing values of pixels in TIFF files: Headers, IFD and so on and even succeeded in writing a program on pure C but the problem is that i don't see how it can help in displaying images in C#. I've gone over your program several times and picked and tested the part where you read in rastor from an image: ReadImageFile(ofd.FileName), and in case with a 16 bit TIFF file it was done correctly,i eventually had the rastor ranged from 0 to 65535. So it seemed to be doing well until out of blue i obtained the wrong picture and was absolutely stuck. When i ran your program with a raw data image it also ended up with a 16 bit rastor in the same range obviously, so i don't understand if in both cases i get the rastor how it can display them differently?, i mean TIFF's not correct, i got just contrast lines.
Thank you in advance!
|
|
|
|
|
Two options:
1. Download a free software called ImageJ[^], and see whether your TIFF file opens properly.
2. Post your TIFF file onto some site, and send me the link. I can take a look and see what needs to be done. You need give me a week's time for this, since I have other things to do also.
|
|
|
|
|
Good Day! ImageJ displays my image correctly, even tried to resave it in the same format with it, didn't work, sending you a link to the file
https://spaces.hightail.com/space/Dufw0[^]
access pawsword : vonagu3
Thank you very much for help!
|
|
|
|
|
Hi. Got the file. As I said, I'll need about a week to get this running. So, will revert to you in a week's time. Thanks.
|
|
|
|
|
|
Am still working on it. Would need about 3-4 days more.
|
|
|
|
|
|
Hi! I've been trying to understand the problem with my image and started with going over your code and found some things I don't quite understand: There is a part in the code where you convert 16 bit values to 8bit and after that you save them to row arrays:
sVal = (ushort)(pixels16[i1 + j]);
lPixval = (sVal / 255.0); // Convert to a 255 value range
//lPixval = sVal >> 8;
if (lPixval > 255) lPixval = 255;
if (lPixval < 0) lPixval = 0;
b = (byte)(lPixval);
j1 = j * pixelSize;
row[j1] = b; // Red
row[j1 + 1] = b; // Green
row[j1 + 2] = b;
The question is where in the program row is being displayed as an image?
Thanks!
|
|
|
|
|
Yes - I know I've delayed you; I'm almost at the end of reading in the TIFF file. Am using the ImageJ TiffDecoder.java as basis. Another 40 percent work remaining, I believe. Today and tomorrow, there's some power issue at home, so, will not be able to work on computer
Coming to your specific question:
Member 12116984 wrote: where in the program row is being displayed as an image?
Two places:
1. In the method bnOpenImage_Click() , you find an Invalidate() line immediately after CreateBitmap() . This causes repainting of the screen.
2. There's a method called Form1_Paint() , where there's an invocation to g.DrawImage(...) . Upon invalidation (done in step 1 above), this method is called, like a callback. So, it is here that the image display happens.
Hope this explains. Please write back for any clarifications.
|
|
|
|
|
Thank you! it's all clear now.
|
|
|
|
|
Caution - This is still work in progress, so it has bugs. However, since I'll busy for the next week or so with other stuff, I'm giving this to you in the state it is now.
Good news: It can read your TIFF file.
Bad news: It does not display that image in this ImageDraw application.
Workaround: This program creates a file called rawFile.raw (within C:\Junk - you need to create such a folder), which you can open using my other WPF-based raw image viewing app, again available on this CP site.
Please use these and let me know of any bugs, suggestions, etc. As I said, I can only look into this after about a week. This is not the best code I write, but parts of it are working, and power will be shut down at my place in 10 minutes
Here are two source code files: 1. TiffDecoder.cs, and 2. Form1.cs. Include the TiffDecoder.cs in the project, and overwrite the code for Form1.cs
TiffDecoder.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ImageDraw
{
public class DirectoryEntry
{
public ushort tag;
public ushort type;
public uint count;
public uint valueOfOffset;
}
public class IFD
{
const ushort IMAGE_WIDTH = 256;
const ushort IMAGE_LENGTH = 257;
const ushort BITS_PER_SAMPLE = 258;
const ushort PHOTO_INTERP = 262;
const int IMAGE_DESCRIPTION = 270;
const ushort STRIP_OFFSETS = 273;
const ushort SAMPLES_PER_PIXEL = 277;
const ushort ROWS_PER_STRIP = 278;
const ushort STRIP_BYTE_COUNT = 279;
ushort numberOfEntries;
List<DirectoryEntry> listEntries;
BinaryReader bReader;
TiffDecoder tiffDec;
List<uint> stripOffsets;
List<uint> stripByteCounts;
uint width;
uint height;
public uint samplesPerPixel;
public uint bitsPerSample;
uint rowsPerStrip;
public uint photometricInterpretation;
public List<byte> Pixels8 { get; set; }
public List<byte> Pixels24 { get; set; }
public List<ushort> Pixels16 { get; set; }
public List<int> Pixels16Int { get; set; }
public IFD(BinaryReader br, TiffDecoder tiff)
{
bReader = br;
numberOfEntries = 0;
tiffDec = tiff;
listEntries = new List<DirectoryEntry>();
stripOffsets = new List<uint>();
stripByteCounts = new List<uint>();
Pixels16 = new List<ushort>();
}
public void ReadIfdAndPixelData()
{
numberOfEntries = bReader.ReadUInt16();
listEntries.Capacity = numberOfEntries;
ReadDirectoryEntries();
InterpretDirectoryEntries();
ReadPixelData();
if (samplesPerPixel == 1 && bitsPerSample == 16)
{
tiffDec.Pixels16 = Pixels16;
BinaryWriter bw = new
BinaryWriter(new FileStream("C:\\Junk\\rawFile.raw", FileMode.Create));
for (int i = 0; i < Pixels16.Count; ++i)
{
bw.Write(Pixels16[i]);
}
bw.Close();
}
else
{
}
}
DirectoryEntry ReadNextDirectoryEntry()
{
DirectoryEntry de = new DirectoryEntry();
de.tag = bReader.ReadUInt16();
de.type = bReader.ReadUInt16();
de.count = bReader.ReadUInt32();
de.valueOfOffset = bReader.ReadUInt32();
return de;
}
void ReadDirectoryEntries() {
for (int i = 0; i < numberOfEntries; ++i) {
DirectoryEntry de = ReadNextDirectoryEntry();
listEntries.Add(de);
}
}
void PopulateStripOffsets(DirectoryEntry de)
{
bReader.BaseStream.Seek(de.valueOfOffset, SeekOrigin.Begin);
for (int i = 0; i < de.count; ++i)
{
uint offset = bReader.ReadUInt32();
stripOffsets.Add(offset);
}
}
void PopulateStripByteCounts(DirectoryEntry de)
{
bReader.BaseStream.Seek(de.valueOfOffset, SeekOrigin.Begin);
for (int i = 0; i < de.count; ++i)
{
uint count = bReader.ReadUInt32();
stripByteCounts.Add(count);
}
}
void InterpretDirectoryEntries()
{
for (int i = 0; i < numberOfEntries; ++i) {
InterpretDirectoryEntry(listEntries[i]);
}
}
void ReadPixelData()
{
double stripsPerImage = Math.Floor((height + rowsPerStrip - 1.0)/rowsPerStrip);
uint lastStripNumberOfRows = (uint)(height - rowsPerStrip * ((int)(stripsPerImage) - 1));
uint offset;
ushort pixVal;
if (samplesPerPixel == 1)
{
if (bitsPerSample == 16)
{
Pixels16.Clear();
for (int i = 0; i < stripsPerImage - 1; ++i)
{
offset = stripOffsets[i];
bReader.BaseStream.Seek(offset, SeekOrigin.Begin);
for (int j = 0; j < rowsPerStrip * width; ++j)
{
pixVal = bReader.ReadUInt16();
Pixels16.Add(pixVal);
}
}
offset = stripOffsets[stripOffsets.Count - 1];
bReader.BaseStream.Seek(offset, SeekOrigin.Begin);
for (int j = 0; j < lastStripNumberOfRows * width; ++j)
{
pixVal = bReader.ReadUInt16();
Pixels16.Add(pixVal);
}
pixVal = 5;
}
else
{
}
}
else
{
}
}
void InterpretDirectoryEntry(DirectoryEntry de)
{
switch(de.tag) {
case IMAGE_WIDTH:
width = de.valueOfOffset;
tiffDec.Width = width;
break;
case IMAGE_LENGTH:
height = de.valueOfOffset;
tiffDec.Height = height;
break;
case STRIP_OFFSETS:
PopulateStripOffsets(de);
break;
case STRIP_BYTE_COUNT:
PopulateStripByteCounts(de);
break;
case SAMPLES_PER_PIXEL:
samplesPerPixel = de.valueOfOffset;
break;
case BITS_PER_SAMPLE:
bitsPerSample = de.valueOfOffset;
break;
case ROWS_PER_STRIP:
rowsPerStrip = de.valueOfOffset;
break;
case PHOTO_INTERP:
photometricInterpretation = de.valueOfOffset;
break;
default:
break;
}
}
}
public class TiffDecoder
{
BinaryReader inFile;
String tiffFileName;
bool littleEndian;
IFD ifd;
public TiffDecoder()
{
}
public string FileName { get; set; }
public uint Width { get; set; }
public uint Height { get; set; }
public List<ushort> Pixels16 { get; set; }
int ReadTiffFileHeader()
{
int byteOrder = inFile.ReadInt16();
if (byteOrder == 0x4949)
littleEndian = true;
else if (byteOrder == 0x4d4d)
littleEndian = false;
else
{
inFile.Close();
return -1;
}
int magicNumber = inFile.ReadInt16();
int offset = inFile.ReadInt32();
return offset;
}
public string TiffFileName
{
set
{
tiffFileName = value;
inFile = new BinaryReader(File.Open(tiffFileName, FileMode.Open, FileAccess.Read));
try
{
int firstIfdOffset = ReadTiffFileHeader();
if (firstIfdOffset < 0)
{
inFile.Close();
}
if (firstIfdOffset > 0) {
inFile.BaseStream.Seek(firstIfdOffset, SeekOrigin.Begin);
ifd = new IFD(inFile, this);
ifd.ReadIfdAndPixelData();
}
}
catch
{
}
finally
{
inFile.Close();
}
}
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
namespace ImageDraw
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel panelImage;
private System.Windows.Forms.Button bnOpenImage;
private List<ushort> pixels16;
Graphics g;
uint width, height;
Bitmap bmp;
TiffDecoder tiff;
private System.ComponentModel.Container components = null;
public Form1()
{
InitializeComponent();
pixels16 = new List<ushort>();
g = panelImage.CreateGraphics();
tiff = new TiffDecoder();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.bnOpenImage = new System.Windows.Forms.Button();
this.panelImage = new System.Windows.Forms.Panel();
this.SuspendLayout();
this.bnOpenImage.Location = new System.Drawing.Point(8, 8);
this.bnOpenImage.Name = "bnOpenImage";
this.bnOpenImage.Size = new System.Drawing.Size(88, 56);
this.bnOpenImage.TabIndex = 0;
this.bnOpenImage.Text = "Open Raw Image";
this.bnOpenImage.Click += new System.EventHandler(this.bnOpenImage_Click);
this.panelImage.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.panelImage.Location = new System.Drawing.Point(104, 8);
this.panelImage.Name = "panelImage";
this.panelImage.Size = new System.Drawing.Size(512, 512);
this.panelImage.TabIndex = 2;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(624, 530);
this.Controls.Add(this.panelImage);
this.Controls.Add(this.bnOpenImage);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Display 16-bit Raw Image Files";
this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void bnOpenImage_Click(object sender, System.EventArgs e)
{
pixels16.Clear();
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "TIFF Files(*.tif)|*.tif";
ofd.ShowDialog();
if( ofd.FileName.Length > 0 )
{
tiff.TiffFileName = ofd.FileName;
width = tiff.Width;
height = tiff.Height;
pixels16 = tiff.Pixels16;
CreateBitmap();
Invalidate();
}
ofd.Dispose();
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
if( pixels16.Count > 0 )
g.DrawImage(bmp, 0, 0);
}
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
bmp.Dispose();
pixels16.Clear();
}
private void ReadImageFile(string fileName)
{
BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open));
ushort pixShort;
int i;
long iTotalSize = br.BaseStream.Length;
for( i = 0; i < iTotalSize; i += 2 )
{
pixShort = br.ReadUInt16();
pixels16.Add(pixShort);
}
br.Close();
width = (uint)(Math.Sqrt(pixels16.Count));
height = width;
}
private void CreateBitmap()
{
bmp = new Bitmap((int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
BitmapData bmd = bmp.LockBits(new Rectangle(0, 0, (int)width, (int)height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
unsafe
{
int pixelSize = 3;
int i, j, j1, i1;
byte b;
ushort sVal;
double lPixval;
for (i = 0; i < bmd.Height; ++i)
{
byte* row = (byte*)bmd.Scan0 + (i * bmd.Stride);
i1 = i * bmd.Height;
for (j = 0; j < bmd.Width; ++j)
{
sVal = (pixels16[i1 + j]);
lPixval = (sVal / 256.0);
if( lPixval > 255 ) lPixval = 255;
if( lPixval < 0 ) lPixval = 0;
b = (byte)(lPixval);
j1 = j * pixelSize;
row[j1] = b;
row[j1 + 1] = b;
row[j1 + 2] = b;
}
}
}
bmp.UnlockBits(bmd);
}
}
}
|
|
|
|
|
Oh! Wonderful! there is a lot to think about, thank you!
|
|
|
|
|
Good Evening! I'm writing to say that I figured out the problem with incorrect displaying of my Tiff file. It was in this part of your code:
for (i = 0; i < bmd.Height; ++i)
{
byte* row = (byte*)bmd.Scan0 + (i * bmd.Stride);
i1 = i * bmd.Height; <----- HERE. It should be i1=i*bmd.Width
for (j = 0; j < bmd.Width; ++j)
{
sVal = (pixels16[i1 + j]); <-----Since we move along image strip equaled to Width of
lPixval = (sVal / 256.0); // Convert to a 256 value range Image
if (lPixval > 255) lPixval = 255;
if (lPixval < 0) lPixval = 0;
b = (byte)(lPixval);
j1 = j * pixelSize;
row[j1] = b; // Red
row[j1 + 1] = b; // Green
row[j1 + 2] = b; // Blue
}
}
So at last everything displays correctly! again, Thank you for your contribution! The next step is to process the image with my noise-removal algorithm and make it display the change during processing. Could you direct me to the idea of implementing this?
Thank you in advance!
|
|
|
|
|
Great!. I was also at a loss about where the bug was. Good that you found it out - need to correct it for future versions.
Meanwhile, did you find anything wrong with the TIFF decoder code I posted?
|
|
|
|
|
No! It works correctly, there is a lot of code, I haven't encountered anything wrong so far.
|
|
|
|
|
Hi! I've been changing your program for my purposes and embedded some functionality in it relating to a noise-removal filter , but came across a problem.
I put a button to the form which has to process an image after being pushed and it looks like this:
private void process_btn_Click(object sender, EventArgs e)
{
Algorithm a = new Algorithm(pixels16,width,height);
a.Set_D0_h1_h2_t_lambda_Iter(100, 1, 1, 1, 1,200);
a.Set_sigma(0.5);
a.PeronaMalik(ref pixels16, ref this.progressBar1);
CreateBitmap();
Invalidate();
}
So I have a class called Algorithm and some methods, including a constructor with parameters.
In the constructor I copy List pixels16 to a matrix U[height,width] and do some filtering with a method PeronaMalik, having sent pixels16 as a ref argument, in order to change it within the method, next the same way as in bnOpenImage_Click method I add CreateBitmap and Invalidate for it to be redrawn but nothing happens, I rechecked Algorithm as a console app and everything works well, I get modified pixels16. I'm confused, what am I doing wrong?
Thank you in advance!
|
|
|
|
|
Hi. I have added a button called 'Process' to just halve the pixel values. Here is the code. This works - reduces the intensity of the displayed image.
One word of caution with this code - it directly modifies the pixels16 values. In practice, you should make a copy of these values, so as to have the original values with you, in code.
Tell me if you find anything amiss.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
namespace ImageDraw
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel panelImage;
private System.Windows.Forms.Button bnOpenImage;
private List<ushort> pixels16;
Graphics g;
uint width, height;
Bitmap bmp;
TiffDecoder tiff;
private Button bnProcess;
private System.ComponentModel.Container components = null;
public Form1()
{
InitializeComponent();
pixels16 = new List<ushort>();
g = panelImage.CreateGraphics();
tiff = new TiffDecoder();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.bnOpenImage = new System.Windows.Forms.Button();
this.panelImage = new System.Windows.Forms.Panel();
this.bnProcess = new System.Windows.Forms.Button();
this.SuspendLayout();
this.bnOpenImage.Location = new System.Drawing.Point(8, 8);
this.bnOpenImage.Name = "bnOpenImage";
this.bnOpenImage.Size = new System.Drawing.Size(88, 56);
this.bnOpenImage.TabIndex = 0;
this.bnOpenImage.Text = "Open TIFF Image";
this.bnOpenImage.Click += new System.EventHandler(this.bnOpenImage_Click);
this.panelImage.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.panelImage.Location = new System.Drawing.Point(104, 8);
this.panelImage.Name = "panelImage";
this.panelImage.Size = new System.Drawing.Size(512, 512);
this.panelImage.TabIndex = 2;
this.bnProcess.Location = new System.Drawing.Point(8, 70);
this.bnProcess.Name = "bnProcess";
this.bnProcess.Size = new System.Drawing.Size(88, 23);
this.bnProcess.TabIndex = 3;
this.bnProcess.Text = "Process";
this.bnProcess.UseVisualStyleBackColor = true;
this.bnProcess.Click += new System.EventHandler(this.bnProcess_Click);
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(624, 530);
this.Controls.Add(this.bnProcess);
this.Controls.Add(this.panelImage);
this.Controls.Add(this.bnOpenImage);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Display 16-bit Raw Image Files";
this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void bnOpenImage_Click(object sender, System.EventArgs e)
{
pixels16.Clear();
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "TIFF Files(*.tif)|*.tif";
ofd.ShowDialog();
if( ofd.FileName.Length > 0 )
{
tiff.TiffFileName = ofd.FileName;
width = tiff.Width;
height = tiff.Height;
pixels16 = tiff.Pixels16;
CreateBitmap();
Invalidate();
}
ofd.Dispose();
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
if( pixels16.Count > 0 )
g.DrawImage(bmp, 0, 0);
}
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
bmp.Dispose();
pixels16.Clear();
}
private void ReadImageFile(string fileName)
{
BinaryReader br = new BinaryReader(File.Open(fileName, FileMode.Open));
ushort pixShort;
int i;
long iTotalSize = br.BaseStream.Length;
for( i = 0; i < iTotalSize; i += 2 )
{
pixShort = br.ReadUInt16();
pixels16.Add(pixShort);
}
br.Close();
width = (uint)(Math.Sqrt(pixels16.Count));
height = width;
}
private void CreateBitmap()
{
bmp = new Bitmap((int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
BitmapData bmd = bmp.LockBits(new Rectangle(0, 0, (int)width, (int)height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
unsafe
{
int pixelSize = 3;
int i, j, j1, i1;
byte b;
ushort sVal;
double lPixval;
for (i = 0; i < bmd.Height; ++i)
{
byte* row = (byte*)bmd.Scan0 + (i * bmd.Stride);
i1 = i * bmd.Width;
for (j = 0; j < bmd.Width; ++j)
{
sVal = (pixels16[i1 + j]);
lPixval = (sVal / 256.0);
if( lPixval > 255 ) lPixval = 255;
if( lPixval < 0 ) lPixval = 0;
b = (byte)(lPixval);
j1 = j * pixelSize;
row[j1] = b;
row[j1 + 1] = b;
row[j1 + 2] = b;
}
}
}
bmp.UnlockBits(bmd);
}
private void bnProcess_Click(object sender, EventArgs e)
{
for (int i = 0; i < pixels16.Count; ++i)
{
pixels16[i] /= 2;
}
CreateBitmap();
Invalidate();
}
}
}
|
|
|
|
|