简体   繁体   English

System.Drawing.Image 到 SkiaSharp

[英]System.Drawing.Image to SkiaSharp

I am trying to move my code from using System.Drawing.Image to using SkiaSharp as recommended here .我正在尝试按照此处的建议将我的代码从使用System.Drawing.Image移动到使用SkiaSharp

I trying to find similar operations for working with Tif files from a stream.我试图找到与 stream 中的 Tif 文件一起使用的类似操作。

Currently, the following is what I have using System.Drawing.Image :目前,以下是我使用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();

My current work with SkiaSharp is the following though it does not work correctly.我目前使用 SkiaSharp 的工作如下,但它不能正常工作。 Note: The following code has the following error and I am trying to figure out why in addition to how to select active frames: Unhandled exception. System.ObjectDisposedException: Cannot access a closed Stream.注意:下面的代码有以下错误,我试图弄清楚为什么除了如何 select 活动帧: Unhandled exception. System.ObjectDisposedException: Cannot access a closed Stream. Unhandled exception. System.ObjectDisposedException: Cannot access a closed Stream. likely due to SKCodec codec = SkiaSharp.SKCodec.Create(inStream); Unhandled exception. System.ObjectDisposedException: Cannot access a closed Stream.可能是由于SKCodec codec = SkiaSharp.SKCodec.Create(inStream); but I am not sure why.但我不确定为什么。

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);

These are other things I have tried:这些是我尝试过的其他事情:

  • Using SKCodecOptions to set the FrameIndex but how would I use it since it used for GetPixels() not Decode() .使用 SKCodecOptions 设置FrameIndex但我将如何使用它,因为它用于GetPixels()而不是Decode()
  • There are no properties, I found, that control FrameIndex within a SKBitmap .我发现没有属性可以控制FrameIndex中的SKBitmap
  • The additional conversion from Image to XImage is a bit confusing as from the source here , it appears to be a constructor that creates an XImage straight from an Image .ImageXImage的额外转换有点令人困惑,因为从这里的源代码来看,它似乎是一个直接从Image创建XImage的构造函数。 I would need to create an XImage from a SkiaSharp.SKBitmap instead I believe thought I'm not quite sure how to do this at the moment such as use an existing method like FromStream() though I don't know the differences between the uses necesarily.我需要从SkiaSharp.SKBitmap创建一个XImage而不是我认为我现在不太确定如何执行此操作,例如使用FromStream()之类的现有方法,尽管我不知道用途之间的区别必然地。

You get the exception because decoding SKBitmap with你得到异常,因为解码SKBitmap

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

disposes the inStream .处置inStream

Anyway, to get the particular frame using SkiaSharp, you need to get pixels from the codec:无论如何,要使用 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