Ponteiro bloqueado ao travar um retângulo em um b# bitmap
-
21-08-2019 - |
Pergunta
Isso pode ser uma repetição da seguinte pergunta não respondida:
Ajuda com bitmap bloqueio - format8bppindexed
Estou bloqueando uma imagem da seguinte maneira:
// PixelFormat is 8BppIndexed in my case.
Bitmap bmp = new Bitmap("mySampleImage.tif");
// ClipRectangle will be a Rectangle such as {x=128, y=290, width=250, height=200},
// selected by the user by seeing the image on screen. Thus, it's a valid region
BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
unsafe
{
byte* origin = (byte*)data.Scan0.ToPointer();
// Processing...
}
Na seção de processamento, passo pelos pixels no cliPrectangle na direção y. No entanto, um pixel que deve ser válido retorna com um erro de acesso à memória, dizendo que não posso desreferenciar o ponteiro.
Por exemplo, em uma imagem de 704x600 usando:
ClipRectangle = {x=128, y=290, width=250, height=200}
O pixel (128x321)
deve ser válido. Ao digitar manualmente em matemática para obter esse pixel na janela intermediária, recebo o seguinte:
origin + (321 * stride) + 128 0x053a80c0 *(origin + (321 * stride) + 128): Cannot dereference 'origin + (321 * stride) + 128'. The pointer is not valid.
O Stride é 704, a lógica no meu software cria o local exato do ponteiro como a janela intermediária, então tudo parece certo. Os pixels Y de 290-320 podem ser desreferenciados muito bem. Se eu bloquear o bitmap inteiro, toda a minha lógica prossegue bem, mas tenho dúvidas sobre se estou recebendo os pixels certos ou como o retângulo de travamento é usado em bits.
Por que não posso acessar os pixels previstos esperados no Bitmapdata quando travo apenas a região que preciso?
Solução
Quando você trava os bits usando um retângulo com um deslocamento, BitmapData.Scan0
não retorna o bitmap origem, mas sim a origem do retângulo especificado.
Então, se você usou:
Rectangle rect = new Rectangle(128, 290, 250, 200);
BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
Então o compensação máximo de Scan0
é (250 * Stride) + 200
.
Em outras palavras, o pixel em (128x321) estaria em (Scan0 + (321 - 290) * Stride)
.