C# 生成16位灰度位图数据并保存到文件
我试图用C#从随机数据生成16位灰度位图,但它在Marshal.Copy上崩溃了 这是我的密码:C# 生成16位灰度位图数据并保存到文件,c#,bitmap,C#,Bitmap,我试图用C#从随机数据生成16位灰度位图,但它在Marshal.Copy上崩溃了 这是我的密码: Bitmap b16bpp; private void GenerateDummy16bitImage() { b16bpp = new Bitmap(IMAGE_WIDTH, IMAGE_HEIGHT, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale); var rect =
Bitmap b16bpp;
private void GenerateDummy16bitImage()
{
b16bpp = new Bitmap(IMAGE_WIDTH, IMAGE_HEIGHT, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale);
var rect = new Rectangle(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
var bitmapData = b16bpp.LockBits(rect, ImageLockMode.WriteOnly, b16bpp.PixelFormat);
// Calculate the number of bytes required and allocate them.
var numberOfBytes = bitmapData.Stride * IMAGE_HEIGHT * 2;
var bitmapBytes = new short[numberOfBytes];
// Fill the bitmap bytes with random data.
var random = new Random();
for (int x = 0; x < IMAGE_WIDTH; x++)
{
for (int y = 0; y < IMAGE_HEIGHT; y++)
{
var i = ((y * IMAGE_WIDTH) + x) * 2; // 16bpp
// Generate the next random pixel color value.
var value = (short)random.Next(5);
bitmapBytes[i] = value; // BLUE
bitmapBytes[i + 1] = value; // GREEN
bitmapBytes[i + 2] = value; // RED
// bitmapBytes[i + 3] = 0xFF; // ALPHA
}
}
// Copy the randomized bits to the bitmap pointer.
var ptr = bitmapData.Scan0;
Marshal.Copy(bitmapBytes, 0, ptr, numberOfBytes);//crashes here
// Unlock the bitmap, we're all done.
b16bpp.UnlockBits(bitmapData);
b16bpp.Save("random.bmp", ImageFormat.Bmp);
Debug.WriteLine("saved");
}
位图b16bpp;
私有void generatedummy16bitmage()
{
b16bpp=新位图(图像宽度、图像高度、系统、绘图、成像、像素格式、格式16bppgrayscale);
var rect=新矩形(0,0,图像宽度,图像高度);
var bitmapData=b16bpp.LockBits(rect,ImageLockMode.WriteOnly,b16bpp.PixelFormat);
//计算所需的字节数并分配它们。
var numberOfBytes=位图数据。步长*图像高度*2;
var bitmapBytes=新短[numberOfBytes];
//用随机数据填充位图字节。
var random=新的random();
对于(int x=0;x
例外情况是:
mscorlib.dll中发生“System.AccessViolationException”类型的未处理异常
这不是我的代码。我在32位位图中找到了它并进行了修改。但我想我错过了一些东西,因为我对C#还很陌生
基本上,我所需要的只是将一系列的短片包装到位图数据中。我已经纠正了您的一些错误(大部分是错误的大小)。但是它仍然会在
b16bpp.Save()
上崩溃,因为
位图b16bpp;
私有void generatedummy16bitmage()
{
b16bpp=新位图(图像宽度、图像高度、系统、绘图、成像、像素格式、格式16bppgrayscale);
var rect=新矩形(0,0,图像宽度,图像高度);
var bitmapData=b16bpp.LockBits(rect,ImageLockMode.WriteOnly,b16bpp.PixelFormat);
//计算所需的字节数并分配它们。
var numberOfBytes=位图数据。步长*图像高度;
var bitmapBytes=新短[图像宽度*图像高度];
//用随机数据填充位图字节。
var random=新的random();
对于(int x=0;x
我的更改说明:
已经是bitmapData.Stride
所以不需要乘以2IMAGE\u WIDTH*bytesperpoixel
- 正如您声明的
为bitmappbytes
一样,图像的大小必须以像素为单位,而不是以字节为单位short[]
- 这意味着您也不需要将
乘以2i
- 因为您有一个灰度图像,所以它没有蓝色、绿色和红色通道,只有一个16位的灰色通道
- Copy的长度以“数组单位”为单位,而不是以字节为单位
总之,您尝试将一个数组复制到位图中8倍大。这适用于System.Drawing.Imaging.PixelFormat.Format16bppGrayScale:
private static void SaveBmp(Bitmap bmp, string path)
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
var pixelFormats = ConvertBmpPixelFormat(bmp.PixelFormat);
BitmapSource source = BitmapSource.Create(bmp.Width,
bmp.Height,
bmp.HorizontalResolution,
bmp.VerticalResolution,
pixelFormats,
null,
bitmapData.Scan0,
bitmapData.Stride * bmp.Height,
bitmapData.Stride);
bmp.UnlockBits(bitmapData);
FileStream stream = new FileStream(path, FileMode.Create);
TiffBitmapEncoder encoder = new TiffBitmapEncoder();
encoder.Compression = TiffCompressOption.Zip;
encoder.Frames.Add(BitmapFrame.Create(source));
encoder.Save(stream);
stream.Close();
}
private static System.Windows.Media.PixelFormat ConvertBmpPixelFormat(System.Drawing.Imaging.PixelFormat pixelformat)
{
System.Windows.Media.PixelFormat pixelFormats = System.Windows.Media.PixelFormats.Default;
switch (pixelformat)
{
case System.Drawing.Imaging.PixelFormat.Format32bppArgb:
pixelFormats = PixelFormats.Bgr32;
break;
case System.Drawing.Imaging.PixelFormat.Format8bppIndexed:
pixelFormats = PixelFormats.Gray8;
break;
case System.Drawing.Imaging.PixelFormat.Format16bppGrayScale:
pixelFormats = PixelFormats.Gray16;
break;
}
return pixelFormats;
}
你能详细说明一下“它崩溃了”吗?不是说它会导致崩溃,而是说
Format16bppGrayScale
意味着每个像素没有单独的RGB分量,只有一个16位的值(使用UInt16
而不是有符号的short
类型)@Dai如果我按照你的建议去做的话。复制函数,因为它不能处理Int16[],所以参数错误。顺便说一句,我不理解那些投票结束这个问题的家伙。这有什么问题吗???我在网上搜索了2-3个小时才找到解决方案,但一个也没有找到。你搜索了多长时间与你的问题有多好无关。我投票关闭,因为(当时)你没有给我们任何细节,除了“它崩溃了,这是我的代码”。事实上,“保存到文件”部分是为了调试:)我真的需要在应用程序中使用位图。感谢你的帮助。谢谢。这个答案需要更多的认可。搜索了几个小时后,我终于找到了一个答案,可以在不需要外部库的情况下保存16bpp灰度图像,而且他们只有一票。请注意,这需要导入PresentationCore
。顺便说一句,Format32bppArgb的翻译是不正确的。Bgr32是一种没有alpha的格式。这正是我所需要的。如广告所示,开箱即用。我绝对同意这需要提高。
private static void SaveBmp(Bitmap bmp, string path)
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
var pixelFormats = ConvertBmpPixelFormat(bmp.PixelFormat);
BitmapSource source = BitmapSource.Create(bmp.Width,
bmp.Height,
bmp.HorizontalResolution,
bmp.VerticalResolution,
pixelFormats,
null,
bitmapData.Scan0,
bitmapData.Stride * bmp.Height,
bitmapData.Stride);
bmp.UnlockBits(bitmapData);
FileStream stream = new FileStream(path, FileMode.Create);
TiffBitmapEncoder encoder = new TiffBitmapEncoder();
encoder.Compression = TiffCompressOption.Zip;
encoder.Frames.Add(BitmapFrame.Create(source));
encoder.Save(stream);
stream.Close();
}
private static System.Windows.Media.PixelFormat ConvertBmpPixelFormat(System.Drawing.Imaging.PixelFormat pixelformat)
{
System.Windows.Media.PixelFormat pixelFormats = System.Windows.Media.PixelFormats.Default;
switch (pixelformat)
{
case System.Drawing.Imaging.PixelFormat.Format32bppArgb:
pixelFormats = PixelFormats.Bgr32;
break;
case System.Drawing.Imaging.PixelFormat.Format8bppIndexed:
pixelFormats = PixelFormats.Gray8;
break;
case System.Drawing.Imaging.PixelFormat.Format16bppGrayScale:
pixelFormats = PixelFormats.Gray16;
break;
}
return pixelFormats;
}