|
Yes, you can use Marshal.Copy. However, before that, you need to take care of padding the appropriate number of zeros to make sure that each pixel row is of the correct length (an integral multiple of 4).
|
|
|
|
|
I personaly prefer the Marshal.Copy way mentioned above. You can use PixelFormat.Format32bppRgb and set the fourth byte to a zero, instead of using PixelFormat.Format24bppRgb. After that you don't need take care of row's correct length.
|
|
|
|
|
How to display color raw image?
|
|
|
|
|
I guess it is very similar. I don't have access to a color raw image. If you can please send one or two such files, and the following information:
1. Dimensions of each image - width and height,
2. Whether the pixels are stored as RGBRGBRGB..., or BGRBGRBGR..., or something else,
3. Bits per color per pixel,
to amarnaths.codeproject@gmail.com, I can go through it, and see whether a small application can be written. Please note that I would need about a week for this.
|
|
|
|
|
I need to display 8-bit image. What changes should i make in the code?
|
|
|
|
|
|
I want to display 16 bit raw image which is having 752 width & 1000 height how it will be done???
|
|
|
|
|
Just before the line:
BitmapData bmd = bmp.LockBits(new Rectangle(0, 0, width, height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
you need to specify the new width and height.
Also, to view the complete image, you need to include scrollbars in the panelImage control; or resize panelImage to 752 x 1000.
Hope this answers. Reply back if it does not.
|
|
|
|
|
Dear Amarnath,
Your program is great. Because it gets pixel data without loading image. But I have to read pixel from a jpg file, and I have some data like (W,H,..), but jpg is a complicate format.
please help me
|
|
|
|
|
You can load a JPG file directly in C#. No need to use a Binary Reader. Once you load the image, it is a very simple thing to read the pixels, using the same scanline concept that I have used to create an image on the fly for display.
- Amarnath
|
|
|
|
|
Hi
My picture is very big. For loading it, I must spend 10 second, and it gives a lot of memory too.
I don't want to load my file. I want to use from Binary Reader, because BR dose not need to load file.
But I don't know where is first bit of pixel data. (Where does header be finished?)
My file is 30000*10000. I must read a rectangle from it, for example (x:2000, y:3000, w:500, h:500).
I Wrote this code:
FileStream s1 = new FileStream(@"D:\My Pictures\1.jpg", FileMode.Open, FileAccess.Read);
FileStream s3 = new FileStream(@"D:\My Pictures\26.jpg", FileMode.CreateNew, FileAccess.Write);
BinaryReader br1 = new BinaryReader(s1);
BinaryWriter bw = new BinaryWriter(s3);
Byte byteRead;
int k1 =(int) br1.BaseStream.Length - 1;
br1.BaseStream.Position = 12000000;
for (int j=0; j< 3000;j++)
{
byteRead = br1.ReadByte();
bw.Write(byteRead);
}
br1.Close();
bw.Close();
I chose random int like 12000000 and 3000, but I need to use true value.
Thanks
|
|
|
|
|
I wish it were so simple with JPEG images. It is not so. JPEG is a compressed image format, and most of the JPEG images have undergone lossy compression; with the lossy components being intelligently decided based on the frequency components to which the eye is least sensitive. And different images get compressed to different degrees. You may note this by looking at the file size of two different JPEG images, where the image height and width are the same - these file sizes will be different. (There is one more parameter which affects the degree of compression, but assuming that the parameter value is same, different images get compressed differently).
The entire process of conversion from a BMP or raw pixel-based format to JPEG is in many steps - Colorspace Conversion, Discrete Cosine Transform, Quantization, Zig Zag Scan and finally Huffman coding. Further, since the bits are stored after being Huffman-coded, it is not possible to read them off the file in a straightforward manner. You have to go through the entire process in reverse - Huffman decoding, Inverse zig-zag, Inverse quantization, Inverse Discrete Cosine Transform, etc. Take a look at the JPEG standard at http://www.wotsit.org/list.asp?al=J[^]. The JPEG2000 file format is based on the Wavelet Transform, and is more involved than this.
So, in essence, you cannot simply tell "I want to read rows 50 through 75 from the JPEG file". You need to first decode the JPEG file, and then get to the pixel values. There is an open-source library available at http://www.ijg.org/[^].
|
|
|
|
|
Hello,
I have ported this code to C++/CLI, when I realised that there seems to be an incorrect calculation of i1.
It works if you use rectangular images, but this is almost never the case.
Instead of using:
byte* row = (byte*)bmd.Scan0 + (i * bmd.Stride);
i1 = i * bmd.Height;
It should be:
byte* row = (byte*)bmd.Scan0 + (i * bmd.Stride);
i1 = i * bmd.Width;
Thanks
- Justin
|
|
|
|
|
Yes - you are right. For rectangular images, you have to modify the code as suggested by you. However, under my assumption of square images, the program works fine.
|
|
|
|
|
Hi i'm using C# in visual estudio 2005, i need to open 16 bits png images, not raw images. i have a code in which one i can open a 8 bit image and i can get a pixel from that image. the code works, but what i need is to open a 16 bit images. i need your help. thankyou. some of the code i have is the next:
-------------------------------------------------------------------------------------------------------------------------
private void pictureBox_Click(object sender, System.EventArgs e)
{
int[] pos = new int[2];
pos = m_Coord.GetXY();
if (this.pictureBox.Image != null)
if ((pos[0]<this.pictureBox.Image.Width) && (pos[1]<this.pictureBox.Image.Height))
{
m_Coord.AgregarPunto(pos);
// para obtener color
Bitmap b = (Bitmap)this.pictureBox.Image;
int[] color = new int[3] ;
unsafe
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
byte * p = (byte *)(void *)Scan0;
p += pos[1]*stride + pos[0]*3;
color[0] = (int)p[2];
color[1] = (int)p[1];
color[2] = (int)p[0];
b.UnlockBits(bmData);
}
FormPadre f = (FormPadre)this.ParentForm;
f.statusBar.Panels[1].Text = "Click=(" + System.Convert.ToString(pos[0]) + "," + System.Convert.ToString(pos[1]) + ")";
f.statusBar.Panels[2].Text = "RGB =" + System.Convert.ToString(color[0])+ "," +System.Convert.ToString(color[1])+ "," + System.Convert.ToString(color[2]);
g = this.pictureBox.CreateGraphics();
g.DrawEllipse(pen, pos[0] - 3, pos[1] - 3, 6, 6);
}
else
{
MessageBox.Show("El punto está fuera de los límites de la imagen", "Important", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
----------------------------------------------------------------------------------------------------------------------------------------
above, there are some functions that i have in other clases. what i need is to open 16 bit png images.
i have tried doing the next: but the intensity pixel values are not corrects
---------------------------------------------------------------------------------------------------------------------------------------
private void pictureBox_Click(object sender, System.EventArgs e)
{
int[] pos = new int[2];
pos = m_Coord.GetXY();
if (this.pictureBox.Image != null)
if ((pos[0]<this.pictureBox.Image.Width) && (pos[1]<this.pictureBox.Image.Height))
{
m_Coord.AgregarPunto(pos);
// para obtener color
Bitmap b = (Bitmap)this.pictureBox.Image;
int[] color = new int[3];
unsafe
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, b.PixelFormat);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
byte* p = (byte*)(void*)Scan0;
p += pos[1]*stride + pos[0]*6;
color[0] =(int)p[2];
color[1] =(int)p[1];
color[2] =(int)p[0];
b.UnlockBits(bmData);
}
FormPadre f = (FormPadre)this.ParentForm;
f.statusBar.Panels[1].Text = "Click=(" + System.Convert.ToString(pos[0]) + "," + System.Convert.ToString(pos[1]) + ")";
f.statusBar.Panels[2].Text = "RGB =" + System.Convert.ToString(color[0])+ "," +System.Convert.ToString(color[1])+ "," + System.Convert.ToString(color[2]);
g = this.pictureBox.CreateGraphics();
g.DrawEllipse(pen, pos[0] - 3, pos[1] - 3, 6, 6);
}
else
{
MessageBox.Show("El punto está fuera de los límites de la imagen", "Important", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
------------------------------------------------------------------------------------------------------------------------------------
please help me
|
|
|
|
|
Hi
Please tell me how to read pixel data from an image so that i can use it as a raw data to display that image.
Thanks
Sandeep
|
|
|
|
|
Hi Sandeep,
Your question is quite generic, and needs an very elaborate answer.
You have to identify these parameters from the image file: the width of the image, the height of the image, the bits per pixel, the location (in the image file) where the pixel data starts. If you know these things, it is easy to read the pixel data. Reading the pixel data (in C#) is done by using the methods of Binary Reader classes. In C, you can use the fread() function.
One important thing you need to understand is the file format. Information on these formats would be available on the Internet. One useful book to refer to is "Encyclopaedia of Graphic File Formats", published by O'Reilly. That book explains the basics, and gives necessary explanations on the different formats. For BMP, you should go through the Microsoft documentation. For TIFF, you should read the TIFF standard. Remember one thing - reading a JPEG image is not easy because JPEG is a compressed file format; in JPEG, the data is stored after DCT (Discrete Cosine Transform), quantization and Huffman Coding operations are done. In JPEG2000, the wavelet transform is utilized. Other formats are PNG, GIF, DICOM, etc. Each format has its own documentation, and you need to read that documentation thoroughly.
In the article above, I have used a raw format, where just the raw pixel data is stored, without any header in the image file.
Hope this explains. Ask me for any further clarifications.
- Amarnath
|
|
|
|
|
why height is always = height?
|
|
|
|
|
"Width = height" is an assumption I am making in the code. Since we are dealing with raw images, we just know the file size, and the pixel bytes. Image dimensions need to be known apriori, for proper display, and since there is no header, I have assumed that the image is square. My intention in this article is to show how to display a raw file - reading it through a Binary Reader, creating the bitmap on the fly, and then displaying it. A simple extension of this program is to have a small dialog (before bitmap creation / display) prompting the user about the image width and height, and use these dimensions while creating / displaying the image.
|
|
|
|
|
So how do you deal with rectangular images?
|
|
|
|
|
Quite simple. For a rectangular raw image, you should apriori know the width and height. So, after the File Open dialog, introduce yet another dialog prompting the user to enter width and height. Then, use these width and height values while displaying the image. If you see my code, I just take the square root of "half the file size" (as I am working with 16-bit raw images) - you also need to remove these lines of code.
|
|
|
|
|