Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我会出现这个错误';具有索引像素格式的图像不支持SetPixel“;_C#_Image Thresholding - Fatal编程技术网

C# 为什么我会出现这个错误';具有索引像素格式的图像不支持SetPixel“;

C# 为什么我会出现这个错误';具有索引像素格式的图像不支持SetPixel“;,c#,image-thresholding,C#,Image Thresholding,我正在尝试对图像进行阈值处理。类型为“tif”的图像,我得到的错误是 具有索引像素格式的图像不支持SetPixel 这是我的代码,p11是图像名称 for (int r = 0; r < p11.Width; r++) { // whiteColor = 0; // blackColor = 0; for (int c = 0; c < p11.Height; c++) { num1 = int.Parse(p11.GetPixel

我正在尝试对图像进行阈值处理。类型为“tif”的图像,我得到的错误是

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

这是我的代码,
p11
是图像名称

for (int r = 0; r < p11.Width; r++)
{
    //  whiteColor = 0;
    //  blackColor = 0;
    for (int c = 0; c < p11.Height; c++)
    {
        num1 = int.Parse(p11.GetPixel(r, c).A.ToString()); // gets the alpha component value of this colout
        num2 = int.Parse(p11.GetPixel(r, c).B.ToString()); // gets the Blue component value of this colout
        num3 = int.Parse(p11.GetPixel(r, c).R.ToString()); // gets the Red component value of this colout
        num4 = int.Parse(p11.GetPixel(r, c).G.ToString()); // gets the green component value of this colout

        if( T <= num1 && T <= num2 && T <= num3 && T <= num4)
        {

        }
        else
        {
            p11.SetPixel(r, c, Color.Black);
        }
    }
}
for(int r=0;r如果(T索引像素格式是指图像数据不包含直接颜色,而是包含调色板的条目,调色板间接引用颜色。8位及以下的每像素图像通常是索引图像。要访问实际颜色列表,请参阅
位图的
调色板
属性

SetPixel
不能用于这些图像,因为它需要颜色作为参数。要操作图像内容,需要通过
LockBits
方法获得
BitmapData
。在下面的示例中,
TransformColor
获取调色板索引并返回另一个索引

private unsafe static void ManipulateIndexedBitmap(Bitmap bitmap)
{
    int bpp = Image.GetPixelFormatSize(bitmap.PixelFormat);

    BitmapData bitmapData = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), ImageLockMode.ReadWrite, bitmap.PixelFormat);
    try
    {
        byte* line = (byte*)bitmapData.Scan0;

        // scanning through the lines
        for (int y = 0; y < bitmapData.Height; y++)
        {
            // scanning through the pixels within the line
            for (int x = 0; x < bitmapData.Width; x++)
            {
                switch (bpp)
                {
                    // a pixel is 1 byte - there are up to 256 palette entries 
                    case 8:
                        line[x] = (byte)TransformColor(line[x]);
                        break;
                    // a pixel is 4 bits - there are up to 16 palette entries
                    case 4:
                        // First pixel is the high nibble
                        int pos = x >> 1;
                        byte nibbles = line[pos];
                        if ((x & 1) == 0)
                        {
                            nibbles &= 0x0F;
                            nibbles |= (byte)(TransformColor(nibbles) << 4);
                        }
                        else
                        {
                            nibbles &= 0xF0;
                            nibbles |= (byte)TransformColor(nibbles >> 4);
                        }

                        line[pos] = nibbles;
                        break;
                    // a pixel is 1 bit - there are exactly two palette entries
                    case 1:
                        // First pixel is MSB.
                        pos = x >> 3;
                        byte mask = (byte)(128 >> (x & 7));
                        if (TransformColor(((line[pos] & mask) == 0) ? 0 : 1) == 0)
                            line[pos] &= (byte)~mask;
                        else
                            line[pos] |= mask;
                        break;
                }
            }

            line += bitmapData.Stride;
        }
    }
    finally
    {
        bitmap.UnlockBits(bitmapData);
    }
}
private不安全静态无效操作IndexedBitmap(位图)
{
int bpp=Image.GetPixelFormatSize(位图.PixelFormat);
BitmapData BitmapData=bitmap.LockBits(新矩形(Point.Empty,bitmap.Size),ImageLockMode.ReadWrite,bitmap.PixelFormat);
尝试
{
字节*行=(字节*)bitmapData.Scan0;
//扫线
对于(int y=0;y>1;
字节半字节=行[pos];
如果((x&1)==0)
{
半字节&=0x0F;
半字节|=(字节)(转换颜色(半字节)>4);
}
行[pos]=字节;
打破
//一个像素为1位-正好有两个调色板条目
案例1:
//第一个像素是MSB。
pos=x>>3;
字节掩码=(字节)(128>>(x&7));
如果(转换颜色)((行[pos]和掩码)==0)?0:1)==0)
行[pos]&=(字节)~掩码;
其他的
行[pos]|=掩码;
打破
}
}
line+=bitmapData.Stride;
}
}
最后
{
位图。解锁位(bitmapData);
}
}

p11
不能是“图像名称”因为您无法对名称调用
SetPixel
。我们所知道的是
p11
具有索引像素格式,因此它包含到颜色表中的索引,而不是RGB颜色。这就是为什么您无法读取或将像素设置为颜色的原因。您应该将TIFF文件转换为RGB格式,以便可以读取和设置颜色。错误确实说明了这一点你需要知道的一切。当你看到你应该查阅SetPixel文档的那一刻,它说:“此函数仅适用于RGBA32、ARGB32、RGB24和Alpha8纹理格式。对于其他格式,SetPixel被忽略。”因此,请正确设置纹理的像素格式,并遵守此处提到的其他要求,这样就可以正常工作。这不是您的问题,但…
GetPixel
/
SetPixel
的速度非常慢。更糟糕的是,对同一像素重复调用
GetPixel
,而不是将其缓存到变量中。有什么问题更糟糕的是,通过调用
ToString
并对结果使用
int.Parse
从ARGB组件中提取整数。这些组件已经是
byte
s了……只需将它们直接转换为
int
或依赖隐式转换:
var color=p11.GetPixel(r,c);num1=color.A;
我尝试集成此代码,但我对
TransformColor
函数一无所知。这是一个现有函数吗?正如我提到的
TransformColor
获取并返回调色板索引。这取决于您如何实现。例如,如果您想替换由索引表示的背景色0(
bitmap.palete.Entries[0]
),则应返回除0之外的输入值。或者,如果您有一个连续的调色板,并且需要,则可以返回
index+1