簡體   English   中英

在C#中調整圖像大小后,為什么會出現錯誤“嘗試讀取或寫入受保護的內存。”?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM