【问题标题】:Reading Pixels from an image byte array从图像字节数组中读取像素
【发布时间】:2013-10-02 14:14:41
【问题描述】:

我有一张 jpeg 图片。我将此位图数据保存到字节数组中。

此 jpeg 的宽度为 100,高度为 100。

我要提取 Rectanlge(10,10,20,20); 的图像

显然,我可以通过这个字节数组进行交互,但我不确定如何将我想要的 x、y 像素与这个字节数组相关联。我知道我必须使用 4 的步幅和像素大小,因为它是 rgba。

我有这个来自这个链接cropping an area from BitmapData with C#

Bitmap bmp = new Bitmap(_file);
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
 BitmapData rawOriginal = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);

int origByteCount = rawOriginal.Stride * rawOriginal.Height;
byte[] origBytes = new Byte[origByteCount];
System.Runtime.InteropServices.Marshal.Copy(rawOriginal.Scan0, origBytes, 0, origByteCount);

int BPP = 4;  
int width = 20;
int height = 20;
int startX = 10;
int startY = 10;

for (int i = 0; i < height; i++)
{
for (int j = 0; j < width * BPP; j += BPP)
{
int origIndex = (startX * rawOriginal.Stride) + (i * rawOriginal.Stride) + (startY * BPP) + (j);
int croppedIndex = (i * width * BPP) + (j);
                        //copy data: once for each channel
for (int k = 0; k < BPP; k++)
{
croppedBytes[croppedIndex + k] = origBytes[origIndex + k];
}
}
}

但是这个:

int origIndex = (startX * rawOriginal.Stride) + (i * rawOriginal.Stride) + (startY * BPP) + (j);

我发现不正确。

有人知道我应该在这里设置什么值吗?

谢谢

【问题讨论】:

    标签: c# bytearray bitmapdata


    【解决方案1】:

    当您使用位图数据时,需要牢记 2 件重要的事情:

    1. BPP(每像素字节数):这里是 4
    2. 步幅(图像的一行上的字节数),此处为 4 * 宽度

    所以如果你想得到一个像素的偏移量,只需使用这个公式:

    int offset = x * BPP + y * stride;
    

    如果您只想提取位图的一部分,您可以这样做:

    int i = 0;
    
    for(int y = startY; y < startY + height; y++)
    {
        for(int k = startX * bpp + y * stride; k < (startX + width) * bpp + y * stride; k++)
        {
            croppedBytes[i] = origBytes[k];
            i++;
        }
    }
    

    【讨论】:

    • "这里应该是 4 * 宽度" - 不完全是,请注意 Stride 总是 BPP * Width。根据宽度可能会有一些填充,请参阅:stackoverflow.com/a/5736076/360211
    • @weston 确实如此,但不适用于 32 位图像(至少目前如此),所以这里确实是 4 * width。我不认为位图操作类针对 64 位处理器进行了优化,这就是为什么我高度怀疑 32 位图像可能存在填充​​span>
    【解决方案2】:

    Stride 是每行字节数 (Y),您不应在任何时候将 x 乘以 Stride

    int y = startY + i;
    int x = startX;
    int origIndex = y * rawOriginal.Stride + x * BPP;
    

    【讨论】:

    • 您好,感谢您的回复。我不知道该怎么办。我自己最终找到了答案。但是你和@ppetrov 都是正确的,应该得到一个绿色的勾号。但我只能做 1 次。我应该在这里发布这个 dliemma 作为问题吗?
    • 不,不要在这里问,像这样的问题继续meta.stackoverflow.com。通常我会奖励给第一个人。 ppetrov 有更多的细节,所以如果这对你有进一步的帮助,请给他打勾。但是,无论您选择谁,您都可以通过点击每个答案旁边的灰色向上箭头来为我们俩投票。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    • 2019-07-23
    相关资源
    最近更新 更多