![](/img/trans.png)
[英]Calling Delphi DLL in c# ““Attempted to read or write protected memory. ” error
[英]Why am I getting an error “Attempted to read or write protected memory.” after resizing image in C#?
我正在使用PHASH來計算大型圖像數據庫的哈希值。 這些圖像具有高分辨率,因此我需要調整它們的大小以快速計算哈希值。
但是,當我調整圖像大小時,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 Paint調整圖像大小,那么它也可以正常工作。
您不需要FileStream
即可打開圖像,您可以使用Bitmap myBmp = Bitmap.FromFile("path");
嘗試刪除文件流。
可以在對ph_dct_imagehash
的調用中找到問題。 這將調用非托管代碼,並且在托管和非托管領域之間的互操作中顯然存在錯誤。
問題中的代碼與該問題無關。 解決方案是使用ph_dct_imagehash
查找並解決問題。
由於您未提供有關ph_dct_imagehash
詳細信息, ph_dct_imagehash
我們無法提供有關執行此操作的任何詳細信息。
這就是我能夠解決答案的方式。
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();
}
我知道resize函數有問題,而不是ph_dct_imagehash函數。
在執行幾乎完全相同的操作時遇到了類似的錯誤-從現有的位圖創建新的位圖。 不同之處在於我們是庄稼,而不是您的安全性gdip行,我們的例外是與您的類在同一類中的另一個.net方法中:本例中為System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageRectRectI。
我們所做的幾乎與您相同(復制位圖,盡管我們裁剪而不是調整大小)。 另外,我們需要在內存中使用位圖,因此我們無法處理最終圖像,但除此之外,它與原始示例的代碼相同。
我們的解決方案是不同的。 即使我們的錯誤發生在裁剪階段的后期復制中,我們也使用了一個第三方庫來提供裁剪后的位圖。
為了測試這是Windows問題還是庫問題,編寫了一種新方法,將原始數據(3通道BGR字節數據)轉換為BMP。 這解決了錯誤。
奇怪的是,我們已有的代碼在其他地方使用了庫的位圖轉換器,而沒有任何問題……這里的區別在於,同一圖像數據在一次處理中被兩次轉換為位圖。 如果將其轉換一次並緩存/重用該句柄,而不是內聯創建兩次,則這也解決了該問題。
要注意的是,如果您使用的是第三方代碼,即使堆棧跟蹤顯示它是.net,也可能是罪魁禍首。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.