c# - 将 PDF 页面渲染到 CGBitmapContext 时如何减少内存使用?

标签 c# objective-c ios xamarin.ios core-graphics

我正在使用下面的代码来呈现 PDF 页面的预览。然而,它正在使用大量内存(每页 2-3MB)。

在我看到的设备日志中:

<Error>: CGBitmapContextInfoCreate: unable to allocate 2851360 bytes for bitmap data

我真的不需要以每个颜色 channel 8 位渲染位图。我如何更改代码以使其以灰度或每 channel 更少的位数呈现?

我也可以使用一个解决方案,其中位图以 x/y 的最大分辨率呈现,然后将生成的图像缩放到请求的大小。之后 PDF 将由 CATiledLayer 进行详细渲染。

此外,根据 Apple 的文档,如果无法创建上下文(由于内存),CGBitmapContextCreate() 将返回 NIL。但是在 MonoTouch 中只有创建上下文的构造函数,因此我无法检查创建是否失败。 如果可以的话,我可以跳过伪装图像。

UIImage oBackgroundImage= null;
using(CGColorSpace oColorSpace = CGColorSpace.CreateDeviceRGB())
// This is the line that is causing the issue.
using(CGBitmapContext oContext = new CGBitmapContext(null, iWidth, iHeight, 8, iWidth * 4, oColorSpace, CGImageAlphaInfo.PremultipliedFirst))
{
    // Fill background white.
    oContext.SetFillColor(1f, 1f, 1f, 1f);
    oContext.FillRect(oTargetRect);

    // Calculate the rectangle to fit the page into. 
    RectangleF oCaptureRect = new RectangleF(0, 0, oTargetRect.Size.Width / fScaleToApply, oTargetRect.Size.Height / fScaleToApply);
    // GetDrawingTransform() doesn't scale up, that's why why let it calculate the transformation for a smaller area
    // if the current page is smaller than the area we have available (fScaleToApply > 1). Afterwards we scale up again.
    CGAffineTransform oDrawingTransform = oPdfPage.GetDrawingTransform(CGPDFBox.Media, oCaptureRect, 0, true);

    // Now scale context up to final size.
    oContext.ScaleCTM(fScaleToApply, fScaleToApply);
    // Concat the PDF transformation.
    oContext.ConcatCTM(oDrawingTransform);
    // Draw the page.
    oContext.InterpolationQuality = CGInterpolationQuality.Medium;
    oContext.SetRenderingIntent (CGColorRenderingIntent.Default);
    oContext.DrawPDFPage(oPdfPage);

    // Capture an image.
    using(CGImage oImage = oContext.ToImage())
    {
        oBackgroundImage = UIImage.FromImage( oImage );
    }
}

最佳答案

I really don't need the bitmap to be rendered in 8bits per color channel.

...

using(CGColorSpace oColorSpace = CGColorSpace.CreateDeviceRGB())

您是否尝试过提供不同的色彩空间?

where the bitmap is rendered in a maximum resolution of x/y

...

using(CGBitmapContext oContext = new CGBitmapContext(null, iWidth, iHeight, 8, iWidth * 4, oColorSpace, CGImageAlphaInfo.PremultipliedFirst))

您也可以控制位图大小和其他直接影响位图需要多少内存的参数。

Also according to Apple's documentation, CGBitmapContextCreate() returns NIL if the context cannot be created (because of memory).

如果返回无效对象(如 null),则 C# 实例将有一个 Handle 等于 IntPtr.Zero。对于任何 ObjC 对象都是如此,因为 init 可以返回 nil 而 .NET 构造函数不能返回 null

关于c# - 将 PDF 页面渲染到 CGBitmapContext 时如何减少内存使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10601544/

相关文章:

ios - textView 如何在不调用 setFrame 的情况下更改其框架

iOS相当于Android的ASyncTask做Http通信

ios - 实时添加的 Firebase 子项未在 Collection View 中更新

c# - 如何监听多个IP地址?

c# - 如何在多个项目的解决方案中管理图标?

c# - ProcessStartInfo 卡在 "WaitForExit"上?为什么?

iphone - 从屏幕上删除键盘而不调用 resignFirstResponder

iphone - 打开多任务时防止应用程序崩溃

IOS 应用间共享数据

c# - C# 中的重载解析、扩展方法和泛型