如何在 C# 中更改索引后显示灰度图像
我有一个从数据库中提取的灰度图像(以字节为单位)。我想使用图形对象在其上绘制一些框,然后显示该图像。这是之前编码的内容 -
public byte[] DrawOverlayOnGreyscaleImage(byte[] buffer, List<ImagingTransaction.ImagingTransactionField> TransactionFieldList, BLLImageType imageType)
{
//Load image into a bitmap object via first going into a MemoryStream
MemoryStream msBitmap = new MemoryStream(buffer);
Bitmap BitmapObj = null;
BitmapObj = new Bitmap(msBitmap);
int bmwidth = BitmapObj.Width;
int bmheight = BitmapObj.Height;
// draw some text on top
Graphics g = Graphics.FromImage(BitmapObj);
由于现在生成图像的方式发生了变化 (Format8bppIndexed),Graphics 对象引发了异常 - “无法从具有索引像素格式的图像创建图形对象”。所以我将位图更改为Format24bppRGB。现在,也不例外。但是当我在图像上画框并尝试保存它后,图像全黑了。这是因为在“灰度”图像的情况下 R=G=B。在将其设为非索引后,该信息会丢失。我将位图更改为再次索引(Format8bbIndexed)。更改调色板,但没有任何帮助。我仍然认为图像是全黑的。请帮忙。我的新代码如下 -
public byte[] DrawOverlayOnGreyscaleImage(byte[] buffer, List<ImagingTransaction.ImagingTransactionField> TransactionFieldList, BLLImageType imageType)
{
//Load image into a bitmap object via first going into a MemoryStream
MemoryStream msBitmap = new MemoryStream(buffer);
Bitmap BitmapObj = null;
BitmapObj = new Bitmap(msBitmap);
int bmwidth = BitmapObj.Width;
int bmheight = BitmapObj.Height;
Bitmap tmp = new Bitmap(BitmapObj.Width, BitmapObj.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(tmp);
Rectangle srcRect;
int RectWidth;
int RectHeight;
Pen myPen = new Pen(System.Drawing.Color.Red, 3);
foreach (ImagingTransaction.ImagingTransactionField Field in TransactionFieldList)
{
// first, do they want to see the rectangles
if (imageType == BLLImageType.GreyScale_With_FieldRectangles || imageType == BLLImageType.GreyScale_With_FieldRectangles_And_Field_Data)
{
RectWidth = Field.LowerRightX - Field.UpperLeftX;
RectHeight = Field.LowerRightY - Field.UpperLeftY;
// sanity check for negative values
if (RectWidth <= 0)
RectWidth = 10;
if (RectHeight <= 0)
RectHeight = 10;
srcRect = new Rectangle(Field.UpperLeftX, Field.UpperLeftY, RectWidth, RectHeight);
g.DrawRectangle(myPen, srcRect);
}
// now, do they want to see the text to the lower right of the field
if (imageType == BLLImageType.GreyScale_With_Field_Data || imageType == BLLImageType.GreyScale_With_FieldRectangles_And_Field_Data)
{
g.DrawString(Field.FieldValue, new Font("Tahoma", 12), Brushes.Red, new PointF(Field.LowerRightX, Field.LowerRightY)); ;
}
}
MemoryStream msBitmapWithRectangle = new MemoryStream();
// Save to memory using the Jpeg format
Bitmap tmp2 = new Bitmap(tmp.Width, tmp.Height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
ColorPalette pal = tmp2.Palette;
for (int i = 0; i < pal.Entries.Length; i++)
{
// create greyscale color table
pal.Entries[i] = Color.FromArgb(i, i, i);
}
tmp2.Palette = pal;
tmp2.Save(msBitmapWithRectangle, System.Drawing.Imaging.ImageFormat.Jpeg);
// read to end
byte[] ByteArrayWithRectangle = msBitmapWithRectangle.GetBuffer();
// cleanup
tmp.Dispose();
tmp2.Dispose();
BitmapObj.Dispose();
msBitmap.Close();
msBitmapWithRectangle.Close();
return ByteArrayWithRectangle;
}
I have a Grayscale image which I am pulling from the DB (it is in Bytes). I want to draw some boxes using graphics object on it and then display this image. This is what was coded before -
public byte[] DrawOverlayOnGreyscaleImage(byte[] buffer, List<ImagingTransaction.ImagingTransactionField> TransactionFieldList, BLLImageType imageType)
{
//Load image into a bitmap object via first going into a MemoryStream
MemoryStream msBitmap = new MemoryStream(buffer);
Bitmap BitmapObj = null;
BitmapObj = new Bitmap(msBitmap);
int bmwidth = BitmapObj.Width;
int bmheight = BitmapObj.Height;
// draw some text on top
Graphics g = Graphics.FromImage(BitmapObj);
Because of the changes in the way the image is now generated (Format8bppIndexed) the Graphics object threw an exception - "A graphics object cannot be created from an image that has an indexed pixel format". So I changed the Bitmap to be Format24bppRGB. Now, there is no exception. But after I draw boxes on the image and try to save it, the image is all black. This is because in case of "Grayscale" images R=G=B. This is lost after making it non indexed. I change the Bitmap to be again Indexed (Format8bbIndexed). Change the ColorPalette, but nothing helps. I still get the image to be totally black. Please help. My new code is as follows -
public byte[] DrawOverlayOnGreyscaleImage(byte[] buffer, List<ImagingTransaction.ImagingTransactionField> TransactionFieldList, BLLImageType imageType)
{
//Load image into a bitmap object via first going into a MemoryStream
MemoryStream msBitmap = new MemoryStream(buffer);
Bitmap BitmapObj = null;
BitmapObj = new Bitmap(msBitmap);
int bmwidth = BitmapObj.Width;
int bmheight = BitmapObj.Height;
Bitmap tmp = new Bitmap(BitmapObj.Width, BitmapObj.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(tmp);
Rectangle srcRect;
int RectWidth;
int RectHeight;
Pen myPen = new Pen(System.Drawing.Color.Red, 3);
foreach (ImagingTransaction.ImagingTransactionField Field in TransactionFieldList)
{
// first, do they want to see the rectangles
if (imageType == BLLImageType.GreyScale_With_FieldRectangles || imageType == BLLImageType.GreyScale_With_FieldRectangles_And_Field_Data)
{
RectWidth = Field.LowerRightX - Field.UpperLeftX;
RectHeight = Field.LowerRightY - Field.UpperLeftY;
// sanity check for negative values
if (RectWidth <= 0)
RectWidth = 10;
if (RectHeight <= 0)
RectHeight = 10;
srcRect = new Rectangle(Field.UpperLeftX, Field.UpperLeftY, RectWidth, RectHeight);
g.DrawRectangle(myPen, srcRect);
}
// now, do they want to see the text to the lower right of the field
if (imageType == BLLImageType.GreyScale_With_Field_Data || imageType == BLLImageType.GreyScale_With_FieldRectangles_And_Field_Data)
{
g.DrawString(Field.FieldValue, new Font("Tahoma", 12), Brushes.Red, new PointF(Field.LowerRightX, Field.LowerRightY)); ;
}
}
MemoryStream msBitmapWithRectangle = new MemoryStream();
// Save to memory using the Jpeg format
Bitmap tmp2 = new Bitmap(tmp.Width, tmp.Height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
ColorPalette pal = tmp2.Palette;
for (int i = 0; i < pal.Entries.Length; i++)
{
// create greyscale color table
pal.Entries[i] = Color.FromArgb(i, i, i);
}
tmp2.Palette = pal;
tmp2.Save(msBitmapWithRectangle, System.Drawing.Imaging.ImageFormat.Jpeg);
// read to end
byte[] ByteArrayWithRectangle = msBitmapWithRectangle.GetBuffer();
// cleanup
tmp.Dispose();
tmp2.Dispose();
BitmapObj.Dispose();
msBitmap.Close();
msBitmapWithRectangle.Close();
return ByteArrayWithRectangle;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
似乎 tmp2 已创建但从未填充原始位图,因此您创建了一个完全黑色的矩形。
Seems that tmp2 is created but never filled with original bitmap, so you create a perfectly black rectangle.
尝试在 BPP 和您需要的大小中创建一个新的位图,并绘制图像,然后绘制矩形。
Try creating a new bitmap in the BPP and size you need, and draw the image, and then draw the rectange.