首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Lockbits从位图中拾取颜色

使用Lockbits从位图中拾取颜色
EN

Stack Overflow用户
提问于 2016-08-03 04:37:19
回答 1查看 1.4K关注 0票数 0

我正在尝试使用LockBits制作颜色选择器,这样当我将光标移到图片框上时,它会显示光标所在位置的颜色。然而,我感兴趣的是如何使用LockBits来实现这一点。

不幸的是,我的尝试总是显示为白色:

代码语言:javascript
复制
void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    Bitmap bmp = new Bitmap(pictureBox1.Image);
    // we will try to get the pixel using raw data and make color from it
    BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);

    // default format is 32bpp argb ( 4 bytes per pixel)
    unsafe
    {
        byte* scanline = (byte*)data.Scan0;
        for(int y = 0; y < data.Height; y++)
        {
            // row
            for (int x = 0; x < data.Width; x+=4)
            {
                 int r = scanline[x];
                 int g = scanline[x+1];
                 int b = scanline[x+2];
                 //int a = scanline[x+3];
                 Color color = Color.FromArgb(255, r, g, b);

                 pictureBox2.BackColor = color;

             }
         }
    }

    bmp.UnlockBits(data);

    //Color color = bmp.GetPixel(e.X, e.Y);

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-03 05:35:49

以下是解决方案:

代码语言:javascript
复制
unsafe Color getPixel(Bitmap bmp, int x, int y)
{
    BitmapData bmData = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height),
                        System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);

    // not a complete check, but a start on how to use different pixelformats
    int pixWidth = bmp.PixelFormat == PixelFormat.Format24bppRgb ? 3 :
                   bmp.PixelFormat == PixelFormat.Format32bppArgb ? 4 : 4;

    IntPtr scan0 = bmData.Scan0;
    int stride = bmData.Stride;
    byte* p = (byte*)scan0.ToPointer() + y * stride;
    int px = x * pixWidth;
    byte alpha = (byte) (pixWidth == 4 ? p[px + 3] : 255);
    Color color  = Color.FromArgb(alpha , p[px + 2], p[px + 1], p[px + 0]);
    bmp.UnlockBits(bmData);
    return color;
}

你可以这样称呼它:

代码语言:javascript
复制
private void panel1_MouseClick(object sender, MouseEventArgs e)
{
    panel2.BackColor = getPixel((Bitmap)panel1.BackgroundImage, e.X, e.Y);
}

当然,您可以使用任何类型的位图源代码,如Label.Image或PictureBox.Image…

颜色通道被称为ARGB,但实际上是有序的BGRA

请注意,stride是位图像素行的物理宽度,包括可能的etra字节以填充为4字节的倍数。

另请注意,其他使用锁定位的解决方案无需指针即可工作。

正如上面的注释所指出的,这实际上比使用GetPixel慢,因为设置不安全的访问向量会消耗任何增益,即使在读出几个像素时也是如此。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38730017

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档