AccessVioilationException с использованием BitmapData в переполнении стека

Ниже моя программа. Я пытаюсь применить фильтр оттенков серого, используя класс bitmapdata в Visual C ++. Я получаю AccessViolationException в 11, помеченный комментарием. Я пытался использовать CLR: Safe и CLR: чисто, но бесполезно. В C # это будет решено с помощью небезопасного блока. Какие-либо предложения? Ни одно из других решений по смежным вопросам не сработало.

 Bitmap^ bmp = gcnew Bitmap(pictureBox1->Image);

BitmapData^ data = bmp->LockBits(Rectangle(0,0,bmp->Width,bmp->Height), ImageLockMode::ReadWrite, PixelFormat::Format24bppRgb);

int blue=0, green=0, red=0;

System::IntPtr s = data->Scan0;

int* P = (int*)(void*)s;

for (int i =0; i<bmp->Height;i++)

{

for (int j = 0; j < bmp->Width*3; j++)

{

blue = (int)P[0];  //access violation exception

green =(int )P[1];

red = (int)P[2];

int avg = (int)((blue + green + red) / 3);

P[0] = avg;

P[1] = avg;

P[2] = avg;

P +=3;

}

}
bmp->UnlockBits(data);
pictureBox1->Image = bmp;

1

Решение

Вы используете int* когда вы должны использовать byte*, Ваши пиксели — три байта каждый, один байт на канал. Ваш int (вероятно) 4 байта, так p[0] возвращает весь пиксель плюс на байте мимо него. Вот почему вы получаете нарушение доступа; Вы превышаете границы буфера изображения.

Когда вы увеличиваете указатель, вы добавляете sizeof *p байты к нему. В этом случае, P += 3 увеличивает указатель P от 12 байт. Слишком много, и вы никогда не сможете прочитать один пиксель (или канал) изображения 24bpp с int*, Вы также предполагаете, что ваш шаг Width * 3, что может быть или не быть правильным (битовые карты выровнены на 4 байта).

Byte* base = (Byte*)data->Scan0;
int stride = data->Stride;

for(int y = 0; y < data->Height; ++y) {
Byte* src = base + y * stride;
for(int x = 0; x < data->Width; ++x, src += 3) {
// bitmaps are stored in BGR order (though not really important here).
// I'm assuming a 24bpp bitmap.
Byte b = src[0];
Byte g = src[1];
Byte r = src[2];
int average = (r + g + b) / 3;
src[0] = src[1] = src[2] = (Byte)average;
}
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]