在课程的顶部,我正在做:
private static Bitmap bmp2 = new Bitmap(@"C:\Temp\New folder (17)\radar001486.GIF");
然后在我正在做的方法中:
private void test()
{
int current_list_length = pointtocolor.Count;
for (int kk=0;kk<current_list_length;kk++)
{
PointF pt = pointtocolor[kk];
e.FillEllipse(cloudColors[cloudColorIndex], pt.X * (float)currentFactor, pt.Y * (float)currentFactor, radius, radius);
bmp2.SetPixel((int)pt.X * (int)currentFactor, (int)pt.Y * (int)currentFactor, Color.Yellow);
}
bmp2.Save(@"c:\temp\yellowbmpcolor.bmp");
}
一旦进入循环,它就会在线上做出异常:
bmp2.SetPixel((int)pt.X * (int)currentFactor, (int)pt.Y * (int)currentFactor, Color.Yellow);
如果我将改变bmp2的实例:
private static Bitmap bmp2 = new Bitmap(@"C:\Temp\New folder (17)\radar001486.GIF");
要
private static Bitmap bmp2 = new Bitmap(512,512);
然后它会工作,但我想SetPixel原始radar001486.GIF上的像素,而不是一个新的空位图。
答案 0 :(得分:6)
问题是你使用的是GIF,因为它有索引像素。如果可以,尝试将其转换为png;或者如果不能,请使用以下方法将其转换为非索引图像:
public Bitmap CreateNonIndexedImage(Image src)
{
Bitmap newBmp = new Bitmap(src.Width, src.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (Graphics gfx = Graphics.FromImage(newBmp)) {
gfx.DrawImage(src, 0, 0);
}
return newBmp;
}
注意:如果您可以选择这样做(即未下载的图像,或者您可以访问服务器),请务必将这些图像转换为PNG。
答案 1 :(得分:3)
您要更改的图片是已编制索引的GIF。这意味着图像不包含一系列具有各自颜色值的像素(正如您的新Bitmap
所做的那样);相反,它包含一个颜色调色板和一系列像素,其索引值放入调色板。从磁盘加载的图像的像素格式可能类似于Format8bppIndexed
。
您无法在此类图片上使用SetPixel
,因为SetPixel
想要直接为像素设置R,G和B值。这不是索引图像的工作原理。
要更改此类图像,您可以选择以下几种方法:
最好的办法是使用WPF,它有GifBitmapEncoder和GifBitmapDecoder。这使您可以将GIF数据解码为WPF可以绘制的内容,然后将其转换回来。由于这使用DirectX而不是GDI +,因此它不具有SetPixel
之类的限制。我真的,真的建议你走这条路,如果可以的话,但如果没有,
将GDI +用于Convert the image到非索引类型的图片,更改图片和convert it back。这通常是一个可怕的想法:GDI +和索引格式不相处,包括将位图编码为索引GIF。图像质量可能很糟糕。
直接编辑字节数据。为此,您需要将GIF数据提取到数组中,并将像素设置为正确的索引值。这里的诀窍是找出正确的指数值;或者,如果调色板中恰好有空的,您可以添加另一个。你需要深入研究GIF格式来解决这个问题,尽管它在空间和速度方面可能是最有效的,而不会降低图像质量。一旦知道要写入的索引值,就可以执行以下操作:
var data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
var bytes = new byte[data.Height * data.Stride];
Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);
bytes[5 * data.Stride + 5] = 1; // Set the pixel at (5, 5) to the color #1
Marshal.Copy(bytes, 0, data.Scan0, bytes.Length);
image.UnlockBits(data);
答案 2 :(得分:0)
问题在于您的图像类型,因为它可以正常使用.jpeg。您可以从Bitmap
获得Image尝试更改为:
private static Bitmap bmp2 = new Bitmap(Image.FromFile(@"C:\Temp\New folder (17)\radar001486.GIF"));
这是我完整的测试代码:
private Bitmap bmp2 = new Bitmap(Image.FromFile(@"e:\temp\temp\yourGIF.gif"));
public Form1()
{
InitializeComponent();
pictureBox1.Image = bmp2;
}
private void button2_Click(object sender, EventArgs e)
{
var sz = bmp2.Size;
for(int x= 0; x<sz.Width; x++)
{
for(int y=0; y<sz.Height; y++)
{
bmp2.SetPixel(x, y, Color.Yellow);
}
}
pictureBox1.Refresh();
}