|
Hi! Your program works perfectly well with 16-bit Raw Data!
if I want to display 10-bit raw image.
I just change code to this.
lPixval = (sVal*64/ 255.0);
Is correct to modified like this?
|
|
|
|
|
Hi! I have continued programming the program and recently decided to improve it functionality by adding the save button, but as always not without problems. My aim is to save processed Tiff image in the same format it was before filtering, nowadays I have found some code and a little changed it to save an image without any compression, but the depth is 24 bit and I understand why since we convert List pixels16 to 8 bit for it to be displayed correctly. Could you help me and share some ideas on how to save images with 16 bit depth?
Here is the code:
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
private void SaveWithoutCompression()
{
ImageCodecInfo myImageCodecInfo;
Encoder myEncoder;
EncoderParameter myEncoderParameter;
EncoderParameters myEncoderParameters;
myEncoder = Encoder.Compression;
myImageCodecInfo = GetEncoderInfo("image/tiff");
myEncoderParameters = new EncoderParameters(1);
myEncoderParameter = new EncoderParameter(myEncoder,
(long)EncoderValue.CompressionNone);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp.Save("ProcessedImage.tiff", myImageCodecInfo, myEncoderParameters);
}
Thank you in advance!
|
|
|
|
|
Hi. Good to know that you're making steady progress.
- Regarding the saving of TIFF file, I would approach in these steps:
- First, saving the processed image in a usual TIFF file; I mean the most convenient TIFF storage possible. Call it "My file".
- Second, identifying the differences between "My file" and "Their file", in terms of format.
- Third, trying to fix these format issues one by one. Approaching all of them simultaneously may make it difficult to handle; so fixing one by one is better.
- Regarding the 16-bit to 8-bit conversion issue, I would recommend this approach. Have these image buffers:
- Original 16-bit image buffer, for as the original reference.
- Modified 16-bit image buffer, the result of image manipulation. When the save operation is done, this buffer will be saved.
- 8-bit image buffer, dynamically generated from the modified 16-bit buffer above, just for display purposes.
Hope this helps. Please write back if this is unclear.
|
|
|
|
|
Thank you! it's clear, i will try this.
|
|
|
|
|
Hi! I've tried to find smth on the internet regarding saving in 16 bit Format and it seems that GDI+ doesn't support it, that is not good for me, since my processed images will go to Tomograph Software which can see images only in this format, so some idea occurred to me: what if I overwrite my original image by new pixels16, that I get after my image has been processed? Is it possible, what do you think?
|
|
|
|
|
Yes, it is a good idea to overwrite the image with the new pixels16; but one difference. Not the original image, but a copy of that original. Programmatically make a copy of the original, and then overwrite the pixels in that copy.
GDI+ does not support saving in 16-bit format. You will have to use BinaryWriter class for this.
|
|
|
|
|
Hi! I've been brainstorming the idea of overwriting the Tiff file and have come to conclusion that creating a processed Tiff file from scratch would be both less time-consuming and more effective since making copies wouldn't be needed. So I'm thinking about constructing a Tiff file with the same Header and IFD. I've gone over again a TiffDecoder Class you posted and the organization of it is absolutely clear for me, but I don't know where to start. Should I use File class as a way of creating a file? Will BinaryWriter class be enough? I mean to create a binary file and fill it with Header, IFD and Changed Values?
Thank you in advance!
|
|
|
|
|
BinaryWriter. This is the class to use to write binary data, into a file. I started working with images back in 1996, and used the C functions fread() and fwrite(). Now, these functions are encapsulated into the BinaryReader and BinaryWriter classes. So, these are to be used.
File class may be OK for text files, but not for such files as these.
|
|
|
|
|
Still decided to create a copy. As you recommended I used BinayWriter and started with making an absolute copy of the image, so I created a BinaryWriter Object:
String tiffFileNameCopy;
outFile = new BinaryWriter(File.Open(tiffFileNameCopy, FileMode.Create, FileAccess.Write));
and then created a method MakeCopy:
public void MakeCopy()
{
byte tmp;
while(outFile.Peekchar() != -1) // <----Checking EOF,I guess smth wrong with this, though
{
tmp = inFile.Read();
outFile.Write(tmp);
}
}
and put it right after the information of the image was written:
public string TiffFileName
{
set
{
tiffFileName = value;
inFile = new BinaryReader(File.Open(tiffFileName, FileMode.Open, FileAccess.Read));
outFile = new BinaryWriter(File.Open(tiffFileNameCopy, FileMode.Create, FileAccess.Write));
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();
}
MakeCopy();
}
catch
{
// Nothing here
}
finally
{
inFile.Close();
}
}
}
But eventually i got the file the size of 45 bytes, What can be wrong with this outFile.Peekchar() != -1? Isn't it a EOF, I tried outFile.Peekchar() > -1 and outFile.Peekchar() > -0.
modified 2-Feb-16 4:16am.
|
|
|
|
|
Try this:
public void MakeCopy()
{
using (FileStream stream = File.OpenRead(tiffFileName))
using (FileStream writeStream = File.OpenWrite(tiffFileNameCopy))
{
BinaryReader reader = new BinaryReader(stream);
BinaryWriter writer = new BinaryWriter(writeStream);
byte[] buffer = new Byte[1024];
int bytesRead;
while ((bytesRead =
stream.Read(buffer, 0, 1024)) > 0)
{
writeStream.Write(buffer, 0, bytesRead);
}
}
}
Also, put the call to MakeCopy() after inFile.Close(); within the finally block.
|
|
|
|
|
Thank you! It works! the next step is changing values
|
|
|
|
|
Wishing you all the best with that step. Need to take care of big endian / little endian here.
|
|
|
|
|
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.
|
|
|
|
|
|