每像素16位图像编辑 [英] 16 Bit per Pixel image editing
问题描述
嗨!
我正在尝试编辑16位图像数据,但无法访问每个像素的完整16位.
以下代码可完美处理8位图像.
Hi!
I´m trying to edit 16 bit image data but I can´t access the full 16 bit of each pixel.
The following code is working flawlessly with 8 bit images.
private void ImageEditing()
{
//opening a 8 bit per pixel jpg image
Bitmap bmp = new Bitmap("Image.jpg");
int Width = bmp.Width;
int Height = bmp.Height;
//creating the bitmapdata and lock bits
System.Drawing.Rectangle rec = new System.Drawing.Rectangle(0, 0, Width, Height);
BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadOnly, bmp.PixelFormat);
unsafe
{
//iterating through all the pixels in y direction
for (int y = 0; y < Height; y++)
{
//getting the pixels of current row
byte* row = (byte*)bmd.Scan0 + (y * bmd.Stride);
//iterating through all the pixels in x direction
for (int x = 0; x < Width; x++)
{
//getting index of current pixel (3 because of the 3 * 8bits per pixel)
int index = x * 3;
//getting R, G and B values
byte R = row[index + 2];
byte G = row[index + 1];
byte B = row[index];
}
}
}
//unlocking bits and disposing image
bmp.UnlockBits(bmd);
bmp.Dispose();
}
如果我想将其调整为16位并用ushorts(无符号16位整数)替换字节,还打开一个16位图像,则可以编译该图像,但在图片中间某处会收到AccesViolationException.
有任何想法我做错了或有不同的解决方法吗?
除了一些有关如何显示Raw image data的文章,在这里或与Google无关,我找不到任何东西.在这种情况下,因为我没有那个.
希望大家能帮忙
Johannes
If I want to adapt it to 16 bit and replace bytes with ushorts(unsigned 16 bit integer) and also open a 16 bit image it compiles but I get an AccesViolationException somewhere in the middle of the picture.
Any ideas what I did wrong or are there any different approches?
I couldn´t find anything here or with google except some article on how to display Raw image data which doesn´t help me in this case as I don´t have that.
I hope you guys can help
Johannes
推荐答案
该代码基本上是正确的,但是它不能普遍起作用,只是因为您的所有移位都取决于您从未使用过的像素格式.您仅将bmp.PixelFormat
作为参数透明地传递给新的位图.除非您分析System.Drawing.PixelFormat
的值(可能需要使用if
或switch
)并相应地移动指针算法,否则代码无法正常工作.请参阅:
http://msdn.microsoft.com/en-us/library/system. drawing.image.pixelformat.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/system. drawing.imaging.pixelformat.aspx [ ^ ].
—SA
The code is basically correct, but it cannot universally work, just because all your shifts will depends on pixel format, which you never use. You only transparently passbmp.PixelFormat
as a parameter to a new bitmap. The code cannot work correctly unless you analyze the value ofSystem.Drawing.PixelFormat
(you might need to useif
orswitch
) and shift your pointer arithmetic accordingly. Please see:
http://msdn.microsoft.com/en-us/library/system.drawing.image.pixelformat.aspx[^],
http://msdn.microsoft.com/en-us/library/system.drawing.imaging.pixelformat.aspx[^].
—SA
我终于找到了解决方法!
因为我将行从字节更改为ushort,所以行的长度只有一半.
因此对于16位图像,代码如下所示:
I finally found the solution!
Because I changed the row from byte to ushort the row has only half the length.
so for a 16 bit image the code would look like this:
private void ImageEditing()
{
//opening a 16 bit per pixel tif image
Bitmap bmp = new Bitmap("Image.tif");
int Width = bmp.Width;
int Height = bmp.Height;
//creating the bitmapdata and lock bits
System.Drawing.Rectangle rec = new System.Drawing.Rectangle(0, 0, Width, Height);
BitmapData bmd = bmp.LockBits(rec, ImageLockMode.ReadOnly, bmp.PixelFormat);
unsafe
{
//iterating through all the pixels in y direction
for (int y = 0; y < Height; y++)
{
//getting the pixels of current row
ushort* row = (ushort*)bmd.Scan0 + (y * bmd.Stride / 2);
//iterating through all the pixels in x direction
for (int x = 0; x < Width; x++)
{
//getting index of current pixel (3 because of the 3 * 16bits per pixel)
int index = x * 3;
//getting R, G and B values
ushort R = row[index + 2];
ushort G = row[index + 1];
ushort B = row[index];
}
}
}
//unlocking bits and disposing image
bmp.UnlockBits(bmd);
bmp.Dispose();
}
这篇关于每像素16位图像编辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!