简体   繁体   English

NSImage和PDFImageRep缓存仍然只能以一种分辨率绘制

[英]NSImage and PDFImageRep caching still draws at only one resolution

I have an NSImage, initialized with PDF data, created like this: 我有一个用PDF数据初始化的NSImage,其创建方式如下:

NSData* data = [view dataWithPDFInsideRect:view.bounds];
slideImage = [[NSImage alloc] initWithData:data];

The slideImage is now the size of the view . slideImage现在是view的大小。

When I try to render the image in an NSImageView , it only draws sharp when the image view is exactly the original size of the image, even if you clear the cache or change the image size. 当我尝试在NSImageView渲染图像时,即使您清除了缓存或更改了图像大小,它也仅在图像视图恰好是图像的原始大小时才绘制清晰的图像。 I tried setting the cacheMode to NSImageCacheNever , which also didn't work. 我尝试将cacheMode设置为NSImageCacheNever ,这也没有用。 The only image rep in the image is the PDF one, and when I render it to a PDF file it shows that it's vector. 图像中唯一的图像表示是PDF,当我将其渲染为PDF文件时,它表示它是矢量。

As a workaround, I create a NSBitmapImageRep with a different size, call drawInRect on the original image, and put the bitmap representation inside a new NSImage and render that, which works, but it feels like it's not optimal: 解决方法是,创建一个具有不同大小的NSBitmapImageRep ,在原始图像上调用drawInRect ,然后将位图表示形式放入新的NSImage然后进行渲染,这是NSBitmapImageRep ,但是感觉并非最佳:

- (NSBitmapImageRep*)drawToBitmapOfWidth:(NSInteger)width
                               andHeight:(NSInteger)height
                               withScale:(CGFloat)scale
{
    NSBitmapImageRep *bmpImageRep = [[NSBitmapImageRep alloc]
                                     initWithBitmapDataPlanes:NULL
                                     pixelsWide:width * scale
                                     pixelsHigh:height * scale
                                     bitsPerSample:8
                                     samplesPerPixel:4
                                     hasAlpha:YES
                                     isPlanar:NO
                                     colorSpaceName:NSCalibratedRGBColorSpace
                                     bitmapFormat:NSAlphaFirstBitmapFormat
                                     bytesPerRow:0
                                     bitsPerPixel:0
                                     ];
    bmpImageRep = [bmpImageRep bitmapImageRepByRetaggingWithColorSpace:
                   [NSColorSpace sRGBColorSpace]];
    [bmpImageRep setSize:NSMakeSize(width, height)];
    NSGraphicsContext *bitmapContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:bmpImageRep];
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:bitmapContext];

    [self drawInRect:NSMakeRect(0, 0, width, height) fromRect:NSZeroRect operation:NSCompositeCopy fraction:1];

    [NSGraphicsContext restoreGraphicsState];
    return bmpImageRep;
}

- (NSImage*)rasterizedImageForSize:(NSSize)size
{
    NSImage* newImage = [[NSImage alloc] initWithSize:size];
    NSBitmapImageRep* rep = [self drawToBitmapOfWidth:size.width andHeight:size.height withScale:1];
    [newImage addRepresentation:rep];
    return newImage;
}

How can I get the PDF to render nicely at any size without resorting to hacks like mine? 如何获得PDF来以任意大小很好地呈现而不用像我这样的黑客?

The point of NSImage is that you create it with the size (in points) that you want it to be. NSImage的要点是您使用所需的大小(以NSImage为单位)来创建它。 The backing representation can be vector based (eg PDF), and the NSImage is resolution independent (ie it supports different pixels per point), but the NSImage still has a fixed size (in points). 支持表示可以基于矢量(例如PDF),并且NSImage是与分辨率无关的(即,每个点支持不同的像素),但是NSImage仍然具有固定的大小(以点为单位)。

One one the points of an NSImage is that it will / can add a cache representation to speed up subsequent drawing. NSImage的要点之一是,它将/可以添加缓存表示以加快后续绘制的速度。

If you need to draw a PDF to multiple sizes, and you want to use an NSImage, you're probably best of creating an NSImage for your given target size. 如果您需要将PDF绘制为多种尺寸,并且要使用NSImage,则最好为给定的目标尺寸创建一个NSImage。 If you want to, you can keep the NSPDFImageRef around -- I don't think it'll save you much. 如果愿意,可以保留NSPDFImageRef左右-我认为不会为您节省很多。

We tried the following: 我们尝试了以下方法:

NSPDFImageRep* rep = self.representations.lastObject;
return [NSImage imageWithSize:size flipped:NO drawingHandler:^BOOL (NSRect dstRect)
{
    [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
    [rep drawInRect:dstRect fromRect:NSZeroRect operation:NSCompositeCopy fraction:1 respectFlipped:YES hints:@{
            NSImageHintInterpolation: @(NSImageInterpolationHigh)
    }];
    return YES;
}];

And that does give you nice results when scaling up, but makes for blurry images when scaling down. 在放大时确实可以得到不错的结果,但在缩小时却会使图像模糊。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM