포인터를 사용하여 이미지의 줄을 감지하고 해당 줄을 제거하는 프로그램을 만들려고합니다. 현재, 감지 라인 부분은 정말로 잘 작동하고 있으며, 대부분은 라인 부분을 제거하는 것이 효과적입니다. 그러나 약 150-200 개 이미지 이후에이 프로그램은 코드의 안전하지 않은 비트와 관련이없는 장소에서 무작위로 AccessViolationExceptions를 throw합니다.비트 맵 작업에서 무작위 AccessViolationExceptions
// ... Detect lines and such
Bitmap export = new Bitmap(bitmap.Width * 3, bitmap.Height, PixelFormat.Format24bppRgb);
Graphics fg = Graphics.FromImage(export);
fg.DrawImage(bitmap, 0, 0); // Draw the original input bitmap
fg.DrawImage(edited, bitmap.Width, 0); // Draw the input after processing (Line Detection)
try
{
Bitmap lineRemoved = RemoveLines(bitmap, horizontalLines.ToArray(), verticalLines.ToArray()); // Remove lines based on earlier detection
lineRemoved.Save(cellDirectory + "\\Lines\\cell_lr_" + i.ToString("D2") + j.ToString("D2") + ".gif", ImageFormat.Gif); // Save image after removal
fg.DrawImage(lineRemoved, bitmap.Width * 2, 0); // Add image to composite for comparison; This line is what throws the error most of the time
lineRemoved.Dispose();
export.Save(cellDirectory + "\\Lines\\cell" + i.ToString("D2") + j.ToString("D2") + ".gif", ImageFormat.Gif);
}
catch (Exception ex)
{ }
을 :이 코드 후
static unsafe Bitmap RemoveLines(Bitmap input, int[] horizontalLines, int[] verticalLines)
{
Bitmap output;
if (input.PixelFormat == PixelFormat.Format24bppRgb)
{
output = (Bitmap) input.Clone();
}
else
{
output = ConvertTo24bpp((Bitmap)input.Clone());
}
BitmapData bitmapData = output.LockBits(new Rectangle(0, 0, output.Width, output.Height), ImageLockMode.ReadWrite, output.PixelFormat);
int w = output.Width;
int h = output.Height;
int bpp = 3;
int s = bitmapData.Stride;
byte* p = (byte*) bitmapData.Scan0;
for (int r = 0; r < h; r++)
{
for (int c = 0; c < h; c++)
{
if (horizontalLines.Contains(r) || verticalLines.Contains(c))
{
int i = (r * s) + c * bpp;
p[i + 0] = 255;
p[i + 1] = 255;
p[i + 2] = 255;
}
}
}
output.UnlockBits(bitmapData);
return output;
}
, 내가 비교를 위해 다른 비트 맵을 내장뿐만 아니라 결과 비트 맵을 저장
이
라인 제거를 수행하는 비트가 DrawImage 호출은 오류를 발생시키고 항상 AccessViolationException 다음에 InvalidOperationException이옵니다. 오류가 발생한 동안 lineRemoved를 보면 대부분의 멤버가 "InvalidOperationException '유형의 예외를 던졌습니다. 실제 값이 아닌 동일한 비트 맵 앞에있는 한 줄만 있으면 문제가 없습니다. 입력 비트 맵은 코드 전체에서 변경되지 않고 항상 어떤 방식 으로든 변경해야 할 때 복제되거나 다른 비트 맵에 그려집니다.lineRemoved를 저장 한 후에 행을 주석 처리하려고했지만 나중에 동일한 오류가 코드에서 나타납니다. 게다가 try/catch는 실제로 Exception을 잡아 내지는 않습니다. 항상 처리되지 않는다고 말합니다. 그것은 포인터와 관련이 있어야합니다, 그렇지 않으면 나는 이것을 일으키는 것에 관해서는 완전히 잃어버린 것입니다.
(int c = 0; c
에 대한 것이어야합니다. 줄 제거가 전체 이미지에 미치지 못하는 문제가 있었지만 그 문제를 파악하기 위해 우선 순위를 낮추었습니다. 물론이 솔루션은 두 가지 문제 모두에서 동일 할 것입니다. – Abion47
"지연된 embarassing":-) "물론 해결책은 두 가지 문제 모두 동일합니다." 액세스 위반이 사라진 것을 확인합니까? –