2014-01-27 13 views
0

대용량 이미지 데이터베이스의 해시 값 계산에 PHASH를 사용하고 있습니다. 이러한 이미지는 고해상도이므로 해시를 빠르게 계산할 수 있도록 이미지의 크기를 조정해야합니다."보호 된 메모리를 읽거나 쓰려고 시도했습니다."라는 오류 메시지가 나타나는 이유는 무엇입니까? C에서 이미지 크기를 조정 한 후 #?

그러나 이미지 크기를 조정하면 PHASH 프로그램에서 오류가 발생합니다. 크기를 조정하지 않으면 PHASH 프로그램이 정상적으로 작동합니다.

내 크기 조정 코드는 다음과 같습니다.

public void ResizeImage(string ImagePath, int width, int height, string newPath) 
    { 
     Bitmap b = new Bitmap(width, height); 
     using (Graphics g = Graphics.FromImage((Image)b)) 
     { 
      FileStream fs = new FileStream(ImagePath, FileMode.Open); 
      Image img = Image.FromStream(fs); 
      g.DrawImage(img, 0, 0, width, height); 
      fs.Close(); 
     } 
     b.Save(newPath); 
     b.Dispose(); 
    } 

오류는 "보호 된 메모리를 읽거나 쓰려고 시도했습니다."입니다.

phash 코드는 다음과 같습니다 :

ph_dct_imagehash(imagePath, ref hash); 

위의 기능은 C++ 프로그램을 호출하고 나에게 해당 이미지에 대한 해시 값을 반환합니다. 이미지가 프로그래밍 방식으로 크기가 조정되지 않으면 잘 동작합니다. MS 페인트를 사용하여 이미지의 크기를 조정하면 잘 작동합니다.

+0

여기서 phash 코드는 무엇입니까? – techno

+0

@techno, 질문을 업데이트했습니다. –

+0

유효 크기가 조정 된 이미지를 저장했다는 것을 확인했다고 가정하면 어두운 곳에서 촬영됩니다. interop 경계를 원시 코드로 넘어 가면 조기 가비지 수집에 노출됩니다. 'ph_dct_imagehash' 호출 후에'GC.KeepAlive (imagePath)'를 추가하십시오. –

답변

0

이렇게하면 대답을 해결할 수 있습니다.

public void ResizeImage(string ImagePath, int width, int height, string newPath) 
{ 
    Bitmap b = new Bitmap(width, height); 
    using (Graphics g = Graphics.FromImage((Image)b)) 
    { 
     FileStream fs = new FileStream(ImagePath, FileMode.Open); 
     Image img = Image.FromStream(fs); 
     g.CompositingQuality = CompositingQuality.HighSpeed; 
     g.InterpolationMode = InterpolationMode.HighQualityBicubic; 
     g.CompositingMode = CompositingMode.SourceCopy; 
     g.DrawImage(img, 0, 0, width, height); 
     fs.Close(); 
    } 
    b.Save(newPath); 
    b.Dispose(); 
} 

나는 ph_dct_imagehash 함수가 아니라 resize 함수에 약간의 문제가 있음을 알고있었습니다.

0

당신은 당신은 단지 Bitmap myBmp = Bitmap.FromFile("path");

이 파일 스트림을 제거해보십시오 사용할 수있는 이미지를 엽니 다 FileStream 필요하지 않습니다.

+0

그것이 제가 한 첫 번째 일이었습니다. 동료가 FileStream을 사용하도록 제안 했으므로 사용했습니다. 두 경우 모두 작동하지 않습니다. :-( –

+0

왜 그래픽을 만들 때 (이미지) b를 사용합니까? 그냥 사용하십시오 – techno

+0

"이미지"라는 키워드를 제거하려고 했는데도 여전히 문제가 해결되지 않았지만 여전히 "읽거나 쓰려고 시도했습니다. 이것은 종종 다른 메모리가 손상되었음을 나타냅니다. " –

0

ph_dct_imagehash으로 전화하여 문제를 찾을 수 있습니다. 이렇게하면 관리되지 않는 코드가 호출되며 관리되는 영역과 관리되지 않는 영역 사이에 interop 오류가 있음을 분명히 알 수 있습니다.

문제의 코드는 문제와 관련이 없습니다. 해결책은 ph_dct_imagehash을 사용하여 문제를 찾아 수정하는 것입니다.

ph_dct_imagehash에 대한 세부 정보를 제공하지 않았으므로이를 수행하는 방법에 대해 자세히 설명해 드릴 수 없습니다.

0

거의 동일한 똑같은 작업을 수행하여 기존 비트 맵에서 새 비트 맵을 만들었습니다. 차이점은 우리가 농작물이었고 안전 gDip 행 대신 우리의 예외는 우리 클래스의 System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageRectRectI와 동일한 클래스의 다른 .net 메서드에있었습니다.

우리는 비트 맵을 복사하는 대신 크기를 조정하지 않고 자르기는했지만 거의 똑같은 작업을 수행했습니다. 또한 최종 이미지를 처리 ​​할 수 ​​없도록 메모리에 비트 맵이 필요했지만 원래 이미지와 동일한 코드였습니다.

우리의 솔루션은 다릅니다. 비록 우리의 오류가 작물 단계에서 포스트 카피를하고 있었음에도 불구하고 우리는 자른 비트 맵을 제공 한 타사 라이브러리를 사용했습니다.

Windows 문제인지 또는 라이브러리 문제인지 테스트하려면 원래 데이터 (3 채널 BGR 바이트 데이터)를 BMP로 변환하는 새로운 방법을 작성하십시오. 이렇게하면 오류가 해결되었습니다.

이상하게도 우리는 라이브러리의 비트 맵 변환기를 다른 곳에서 사용하는 기존 코드를 가지고있었습니다 ...차이점은 동일한 이미지 데이터가 단일 처리 실행의 일부로 두 번 비트 맵으로 변환된다는 점입니다. 한 번 변환 한 다음 두 번 인라인으로 작성하지 않고 캐시를 다시 작성/재사용하면 문제가 해결됩니다.

타사 코드를 사용하고 있다면 스택 추적에서 .net이라고 표시되는 경우에도 문제가 될 수 있습니다.