我正在尝试创建一个具有纯色背景的8位图像。它看起来应该非常直接,但文件中的详细信息将其列为32位颜色深度。我遗漏了什么?
public void CreateImage()
{
var bmpOut = new Bitmap(300, 300);
var g = Graphics.FromImage(bmpOut);
g.FillRectangle(new SolidBrush(Color.Gray), 0, 0, 300, 300);
var stream = new MemoryStream();
bmpOut.Save(stream, GetPngCodecInfo(), GetEncoderParameters());
bmpOut.Save(@"C:\image.png", GetPngCodecInfo(), GetEncoderParameters());
}
public EncoderParameters GetEncoderParameters()
{
var parameters = new EncoderParameters();
parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8);
return parameters;
}
public ImageCodecInfo GetPngCodecInfo()
{
var encoders = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo codecInfo = null;
foreach (var imageCodecInfo in encoders)
{
if (imageCodecInfo.FormatID != ImageFormat.Png.Guid)
continue;
codecInfo = imageCodecInfo;
break;
}
return codecInfo;
}发布于 2013-03-26 13:00:15
使用此构造函数指定像素格式:http://msdn.microsoft.com/en-us/library/3z132tat.aspx
由于无法从索引像素格式创建图形,因此只能将原始像素写入8位图像。
Bitmap bitmap = new Bitmap(32, 32, PixelFormat.Format8bppIndexed);
var bitmapData = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), ImageLockMode.ReadWrite, bitmap.PixelFormat);
Random random=new Random();
byte[] buffer=new byte[bitmap.Width*bitmap.Height];
random.NextBytes(buffer);
Marshal.Copy(buffer,0,bitmapData.Scan0,buffer.Length);
bitmap.UnlockBits(bitmapData);
bitmap.Save("test.bmp",ImageFormat.Bmp);您可以在WinForms上使用以下代码:http://www.codeproject.com/Articles/17162/Fast-Color-Depth-Change-for-Bitmaps
或者,如果你可以从WPF中引用这个类,那就容易多了:http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.formatconvertedbitmap(v=vs.85).aspx
发布于 2013-03-27 22:07:44
您也可以创建更高比特率的图像,然后在保存之前将其转换为8位。这将允许您在创建图像时使用图形上下文。有关如何转换为8位的建议,请参阅此问题:C# - How to convert an Image into an 8-bit color Image?
发布于 2013-03-26 11:02:20
使用System.Runtime.InteropServices;使用System.Linq;使用System.Drawing.Imaging;使用System.Drawing;使用系统;公共静态分部类ImageExtensions {公共静态ColorPalette ToGrayScale(此ColorPalette调色板){ var entries=palette.Entries;for(var i=entries.Length;i-->0;entriesi=entriesi.ToGrayScale());返回调色板;}公共静态颜色ToGrayScale(this Color color,double[] luminance=null) { var list=(亮度??new[]{ 0.2989,0.5870,0.1140 }).ToList();var channel=new[] { color.R,color.G,color.B };var c=(字节)Math.Round(list.Sum(x => x*channellist.IndexOf(X);return Color.FromArgb(c,c,c);}公共静态位图To8bppIndexed(此位图原件){ var rect=new Rectangle(Point.Empty,original.Size);var pixelFormat=PixelFormat.Format8bppIndexed;var destination=new位图(rect.Width,rect.Height,pixelFormat);使用( var source=original.Clone(rect,PixelFormat.Format32bppArgb)) { var destinationData=destination.LockBits(rect,ImageLockMode.WriteOnly,pixelFormat);var sourceData=source.LockBits(rect,ImageLockMode.ReadOnly,source.PixelFormat);var destinationSize=destinationData.Stride*destinationData.Height;var var bytedestinationSize;var sourceBuffer=new bytesourceSize;Marshal.Copy(sourceData.Scan0,sourceBuffer,0,sourceSize);source.UnlockBits(sourceData);var var list=destination.Palette.Entries.ToList();对于( var y=destination.Height;y-->0;){ for(var x=destination.Width;x-->0;){ var pixelIndex=y*destination.Width+x;var sourceIndex=4*pixelIndex;var color= Color.FromArgb( sourceBuffer0+sourceIndex,sourceBuffer1+sourceIndex,sourceBuffer2+sourceIndex,sourceBuffer3+sourceIndex ).ToGrayScale();destinationBufferpixelIndex=(byte)list.IndexOf(color);}} Marshal.Copy(destinationBuffer,0,destinationData.Scan0,destinationSize);destination.UnlockBits(destinationData);}返回目的地;} }
在将其保存到文件之前调用bmpOut=bmpOut.To8bppIndexed();。
https://stackoverflow.com/questions/15628385
复制相似问题