簡體   English   中英

System.Drawing.Image 到 SkiaSharp

[英]System.Drawing.Image to SkiaSharp

我正在嘗試按照此處的建議將我的代碼從使用System.Drawing.Image移動到使用SkiaSharp

我試圖找到與 stream 中的 Tif 文件一起使用的類似操作。

目前,以下是我使用System.Drawing.Image的內容:

System.Drawing.Image MyImage = System.Drawing.Image.FromStream(inStream);
PdfDocument doc = new PdfDocument();

for (int PageIndex = 0; PageIndex < MyImage.GetFrameCount(FrameDimension.Page); PageIndex++)
{
    MyImage.SelectActiveFrame(FrameDimension.Page, PageIndex);
    XImage img = XImage.FromGdiPlusImage(MyImage);
    var page = new PdfPage();

    page.Width = MyImage.Width;
    page.Height = MyImage.Height;
    doc.Pages.Add(page);
    XGraphics xgr = XGraphics.FromPdfPage(doc.Pages[PageIndex]);
    xgr.DrawImage(img, 0, 0, page.Width, page.Height);
}

doc.Save(outStream);
MyImage.Dispose();

我目前使用 SkiaSharp 的工作如下,但它不能正常工作。 注意:下面的代碼有以下錯誤,我試圖弄清楚為什么除了如何 select 活動幀: Unhandled exception. System.ObjectDisposedException: Cannot access a closed Stream. Unhandled exception. System.ObjectDisposedException: Cannot access a closed Stream.可能是由於SKCodec codec = SkiaSharp.SKCodec.Create(inStream); 但我不確定為什么。

PdfDocument doc = new PdfDocument();
doc.Info.CreationDate = new DateTime();

using MemoryStream inStream = new MemoryStream(data);
using var imgStream = new SKManagedStream(inStream, false);
using var skData = SKData.Create(imgStream);
using SKCodec codec = SKCodec.Create(skData);

// TODO: codec is null!

for (int PageIndex = 0; PageIndex < codec.FrameCount; PageIndex++)
{
    SKImageInfo imageInfo = new SKImageInfo(codec.Info.Width, codec.Info.Height);

    // create bitmap stub
    using SKBitmap skBitmap = new SKBitmap(imageInfo);
    IntPtr pixelsPtr = skBitmap.GetPixels();

    // decode particular frame into the bitmap
    codec.GetPixels(imageInfo, pixelsPtr, new SKCodecOptions(PageIndex));

    // encode bitmap back
    using SKData encodedData = skBitmap.Encode(SKEncodedImageFormat.Png, 100);
    using Stream frameStream = encodedData.AsStream();

    XImage img = XImage.FromStream(frameStream);

    var page = new PdfPage();
    doc.Pages.Add(page);
    XGraphics xgr = XGraphics.FromPdfPage(doc.Pages[PageIndex]);
    xgr.DrawImage(img, 0, 0, page.Width, page.Height);
}
doc.Save(destination);

這些是我嘗試過的其他事情:

  • 使用 SKCodecOptions 設置FrameIndex但我將如何使用它,因為它用於GetPixels()而不是Decode()
  • 我發現沒有屬性可以控制FrameIndex中的SKBitmap
  • ImageXImage的額外轉換有點令人困惑,因為從這里的源代碼來看,它似乎是一個直接從Image創建XImage的構造函數。 我需要從SkiaSharp.SKBitmap創建一個XImage而不是我認為我現在不太確定如何執行此操作,例如使用FromStream()之類的現有方法,盡管我不知道用途之間的區別必然地。

你得到異常,因為解碼SKBitmap

SkiaSharp.SKBitmap MyImage = SkiaSharp.SKBitmap.Decode(inStream);

處置inStream

無論如何,要使用 SkiaSharp 獲取特定幀,您需要從編解碼器獲取像素:

using MemoryStream inStream = new MemoryStream(data);
PdfDocument doc = new PdfDocument();
doc.Info.CreationDate = new DateTime();

using SKCodec codec = SkiaSharp.SKCodec.Create(inStream);
for (int PageIndex = 0; PageIndex < codec.FrameCount; PageIndex++)
{
    SKImageInfo imageInfo = new SKImageInfo(codec.Info.Width, codec.Info.Height);

    // create bitmap stub
    using SKBitmap skBitmap = new SKBitmap(imageInfo);
    IntPtr pixelsPtr = skBitmap.GetPixels();

    // decode particular frame into the bitmap
    codec.GetPixels(imageInfo, pixelsPtr, new SKCodecOptions(PageIndex));

    // encode bitmap back
    using SKData encodedData = skBitmap.Encode(SKEncodedImageFormat.Png, 100);
    using Stream frameStream = encodedData.AsStream();

    XImage img = XImage.FromStream(frameStream);

    var page = new PdfPage();

    doc.Pages.Add(page);
    XGraphics xgr = XGraphics.FromPdfPage(doc.Pages[PageIndex]);
    xgr.DrawImage(img, 0, 0, page.Width, page.Height);
}
doc.Save(destination);

暫無
暫無

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

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