簡體   English   中英

使用EncoderParams將MemoryBmp上的Image.Save()轉換為TIFF-如何?

[英]Image.Save() on MemoryBmp to TIFF with EncoderParams - How?

我有一個允許用戶定義圖像區域並將該區域保存到文件的應用程序。 我遇到了我無法解決的障礙。 我創建用於在其上繪制所選區域的位圖粘貼了“ MemoryBmp”的ImageFormat,看來這是為任何非文件加載的位圖設置的ImageFormat。 問題是我的位圖是在內存中創建的,我想將其保存為CCITT4二進制TIFF,但出現“ GDI +中發生一般錯誤”異常。 我非常有信心,這是由於Image.RawFormat屬性是可怕的MemoryBmp。

Image.Save()有一個帶有ImageFormat參數的重載,當我使用傳遞的ImageFormat.Tiff時,它可以很好地保存,但是我沒有機會指定我的編碼器參數。

我能想到的唯一可能的解決方法是使用Image.Save(Image,ImageFormat)保存到磁盤,然后重新加載(RawFormat現在將正確設置為ImageFormat.Tif),然后再次通過編碼器設置保存。 但是,那只是愚蠢的,必須有更好的方法。

以下是一段代碼(這只是測試內容),如果您之前的描述不夠清楚的話,應該可以讓您了解我在做什么:

SizeF dpiScale = GetScreenToImageDPIRatio(loadedImage);
using (Bitmap image = new Bitmap(loadedImage,
    (int)(_cropBox.Width * dpiScale.Width),
    (int)(_cropBox.Height * dpiScale.Height)))
{
    image.SetResolution(loadedImage.HorizontalResolution, 
        loadedImage.VerticalResolution);

    using (Graphics g = Graphics.FromImage(image))
    {
        g.DrawImage(loadedImage, 0, 0, new Rectangle(
            (int)(_cropBox.Location.X * dpiScale.Width),
            (int)(_cropBox.Location.Y * dpiScale.Height),
            (int)(_cropBox.Width * dpiScale.Width),
            (int)(_cropBox.Height * dpiScale.Height)),
            GraphicsUnit.Pixel);
    }

    //  It's stuck as a MemoryBmp so none of these checks will work
    if (true || image.RawFormat.Equals(ImageFormat.Tiff))
    {
        ImageCodecInfo tiffCodecInfo = ImageUtils.GetEncoderInfo("image/tiff");
        EncoderParameters myEncoderParameters = new EncoderParameters(2);

        myEncoderParameters.Param[0] = new
            EncoderParameter(System.Drawing.Imaging.Encoder.Compression,
                (long)EncoderValue.CompressionCCITT4);
        myEncoderParameters.Param[1] = new
            EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 1L);

        image.Save(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".tif"),
            tiffCodecInfo, myEncoderParameters);

        //  The file is a "MemoryBmp" and it's screwing things up
        //image.Save(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".tif"),
        //    ImageFormat.Tiff);
    }
    else
    {
        //  other format saving support, blah blah blah
    }
}

哦,我應該提到“ loadedIimage”確實是一個tiff圖像,我將對loadImage的引用傳遞給Bitmap.ctor()來查看它是否可以提示其正在處理的內容,但沒有任何區別。

弄清楚CCITT4是否需要黑白圖像,哈! 因此,我放棄了谷歌搜索,偶然發現了CodeProject文章,並在源代碼中窺探了一下。 作者提供了一種相當不錯的方法將32bppARGB轉換為1bpp雙色調。 我試用了它,而且速度很快(單個頁面測試顯示大約34毫秒),而且成功了!

我在回答我自己的問題。 我希望這至少可以幫助遇到此問題的其他人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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