C#位图为Format8bppIndexed设置像素值

时间:2019-02-06 12:19:24

标签: c# bitmap

我有一个位图。我想更改所有像素的像素值。有我的代码:

// I use this :
// - int width = 300
// - int height = 400
// - Byte[] matrix = new Byte[width * height]

Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
for (int y = 0; y < height; y++)
{
    for (int x = 0; x < width; x++)
    {
        byte pixValue = matrix[y * width + x];
        Color c = Color.FromArgb(pixValue, pixValue, pixValue);
        bmp.SetPixel(x, y, c);
    }
}

之前,我将这段代码与Bitmap Format24bppRgb一起使用,并且工作正常。现在,我将其与Format8bppIndexed一起使用,但出现错误:

  

具有索引像素格式的图像不支持SetPixel。

我该如何解决?

2 个答案:

答案 0 :(得分:0)

您不能使用contentComponent: (props) => ( <View> <ScrollView> <DrawerUserDetail navigation={props.navigation} /> <DrawerItems {...props} getLabel = {(scene) => ( <View style={{borderBottomWidth:0.5,borderBottomColor: "grey",width:width/1.9}}> <Text style={{color:'#333',fontSize:18,paddingBottom:14,paddingTop:14}}>{props.getLabel(scene)}</Text> </View> )} /> <DrawerCustom navigation={props.navigation} /> </ScrollView> </View> ) ,应该在嵌套的:required{ border: none; border-bottom: 1px solid red; color: red; background: transparent; outline: none; } 中执行以下操作:

SetPixel

答案 1 :(得分:-1)

据我所见,您有一个字节数组,并且想要制作一个包含这些字节作为灰度值的8位图像。这实际上非常简单,因为8位图像中所需的图像数据恰好是该数组中已具有的数据。大致过程是:

  • 使用所需尺寸创建一个新的8位位图。
  • 使用LockBitsMarshal.Copy,将数组的内容逐行复制到图像数据中。请注意,BitmapData内的行长可能与实际图像宽度不同;通常将其舍入为四个字节的下一个倍数。因此,使用数组的BitmapData属性来知道数据中的行宽,从而从数组中每一行的开头复制到Stride中每一行的开头。
  • 索引图像中的像素值实际上不是颜色;它们指的是图像调色板上的索引。因此,为您的图像生成一个从黑色到白色的灰度调色板,因此图像上的每个值均指的是具有完全相同亮度的颜色。

在代码中:

public static Bitmap MatrixToGrayImage(Byte[] matrix, Int32 width, Int32 height)
{
    // Create a new 8bpp bitmap
    Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
    // Get the backing data
    BitmapData data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
    Int64 scan0 = data.Scan0.ToInt64();
    // Copy the contents of your matrix into the image, line by line.
    for (Int32 y = 0; y < height; y++)
        Marshal.Copy(matrix, y * width, new IntPtr(scan0 + y * data.Stride), width);
    bmp.UnlockBits(data);
    // Get the original palette. Note that this makes a COPY of the ColorPalette object.
    ColorPalette pal = bmp.Palette;
    // Generate grayscale colours:
    for (Int32 i = 0; i < 256; i++)
        pal.Entries[i] = Color.FromArgb(i, i, i);
    // Assign the edited palette to the bitmap.
    bmp.Palette = pal;
    return bmp;
}