调整 PDF NSImage OSX
Resize PDF NSImage OSX
我正在更新一个调整图像大小的应用程序 Mac。我想要做的是,如果用户导入要调整大小且具有 PDFImageRep 的图像,则使用我选择的分辨率保存一个新的 PDF 文件。
到目前为止,我已尝试以新尺寸绘制图像,如:
- (NSImage*)imageAtSize:(NSSize)newSize
{
NSImage *resizedImage = [[NSImage alloc] initWithSize:newSize];
[resizedImage lockFocus];
[self drawInRect:NSMakeRect(0, 0, newSize.width, newSize.height)
fromRect:NSMakeRect(0, 0, self.size.width, self.size.height)
operation:NSCompositeSourceOver fraction:1.0];
[resizedImage unlockFocus];
return resizedImage;
}
但这会丢失 PDF 图像表示,因此导致我的保存代码失败。
- (void)saveAsPDFWithOutputDirectory:(NSURL *)outputDirectory size:(NSSize)newSize
{
NSPDFImageRep *pdfRep = [self PDFImageRep];
[pdfRep setSize:newSize];
NSError *error = nil;
[pdfRep.PDFRepresentation writeToURL:outputDirectory options:NSDataWritingAtomic error:&error];
if (error)
{
CLS_LOG(@"Error saving image: %@", error);
}
}
那我该怎么做呢。我将要使用的图像应该是基于矢量的,所以有什么方法可以更新 PDF 上的 属性 以指定新的分辨率?
试试下面的方法。这会创建一个新的 PDF 数据对象,您可以将其保存到文件中。
// pdfData is a CFMutableDataRef
// auxInfo is a CFDictionary
// bounds is your new size in points!
CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData(pdfData);
CGContextRef context = CGPDFContextCreate(consumer, &bounds, auxInfo);
CGPDFContextBeginPage(context, NULL);
NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:gc];
// Your drawing code here
// You probably want to draw your NSImage here in the bounds
[NSGraphicsContext restoreGraphicsState];
CGPDFContextEndPage(context);
CGPDFContextClose(context);
CGContextRelease(context);
CGDataConsumerRelease(consumer);
然后将pdfData保存到文件
感谢 Jacob 提供正确答案。如果有人感兴趣,我用 Jacob 的技术写的完整类别是:
@implementation NSImage (MKBSaveAsPDF)
- (BOOL)isPDF
{
return ([self PDFImageRep] != nil);
}
- (NSPDFImageRep * _Nullable)PDFImageRep
{
for (NSImageRep *imageRep in self.representations)
{
if ([imageRep isKindOfClass:[NSPDFImageRep class]]){
return (NSPDFImageRep*)imageRep;
}
}
return nil;
}
- (void)saveAsPDFWithOutputDirectory:(NSURL *)outputDirectory size:(NSSize)newSize
{
NSPDFImageRep *pdfRep = self.PDFImageRep;
NSMutableData *mutablePDFRef = [[NSMutableData alloc]initWithData:pdfRep.PDFRepresentation];
CFMutableDataRef pdfDataRef = (__bridge CFMutableDataRef)(mutablePDFRef);
CGRect bounds = CGRectMake(0, 0, newSize.width, newSize.height);
CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData(pdfDataRef);
CGContextRef context = CGPDFContextCreate(consumer, &bounds, nil);
CGPDFContextBeginPage(context, NULL);
NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:gc];
[self drawInRect:NSMakeRect(0, 0, newSize.width, newSize.height)];
[NSGraphicsContext restoreGraphicsState];
CGPDFContextEndPage(context);
CGPDFContextClose(context);
CGContextRelease(context);
CGDataConsumerRelease(consumer);
NSError *error = nil;
NSData *pdfData = (__bridge NSData *)(pdfDataRef);
[pdfData writeToURL:outputDirectory options:NSDataWritingAtomic error:&error];
if (error)
{
NSLog(@"Error saving image: %@", error);
}
}
我正在更新一个调整图像大小的应用程序 Mac。我想要做的是,如果用户导入要调整大小且具有 PDFImageRep 的图像,则使用我选择的分辨率保存一个新的 PDF 文件。
到目前为止,我已尝试以新尺寸绘制图像,如:
- (NSImage*)imageAtSize:(NSSize)newSize
{
NSImage *resizedImage = [[NSImage alloc] initWithSize:newSize];
[resizedImage lockFocus];
[self drawInRect:NSMakeRect(0, 0, newSize.width, newSize.height)
fromRect:NSMakeRect(0, 0, self.size.width, self.size.height)
operation:NSCompositeSourceOver fraction:1.0];
[resizedImage unlockFocus];
return resizedImage;
}
但这会丢失 PDF 图像表示,因此导致我的保存代码失败。
- (void)saveAsPDFWithOutputDirectory:(NSURL *)outputDirectory size:(NSSize)newSize
{
NSPDFImageRep *pdfRep = [self PDFImageRep];
[pdfRep setSize:newSize];
NSError *error = nil;
[pdfRep.PDFRepresentation writeToURL:outputDirectory options:NSDataWritingAtomic error:&error];
if (error)
{
CLS_LOG(@"Error saving image: %@", error);
}
}
那我该怎么做呢。我将要使用的图像应该是基于矢量的,所以有什么方法可以更新 PDF 上的 属性 以指定新的分辨率?
试试下面的方法。这会创建一个新的 PDF 数据对象,您可以将其保存到文件中。
// pdfData is a CFMutableDataRef
// auxInfo is a CFDictionary
// bounds is your new size in points!
CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData(pdfData);
CGContextRef context = CGPDFContextCreate(consumer, &bounds, auxInfo);
CGPDFContextBeginPage(context, NULL);
NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:gc];
// Your drawing code here
// You probably want to draw your NSImage here in the bounds
[NSGraphicsContext restoreGraphicsState];
CGPDFContextEndPage(context);
CGPDFContextClose(context);
CGContextRelease(context);
CGDataConsumerRelease(consumer);
然后将pdfData保存到文件
感谢 Jacob 提供正确答案。如果有人感兴趣,我用 Jacob 的技术写的完整类别是:
@implementation NSImage (MKBSaveAsPDF)
- (BOOL)isPDF
{
return ([self PDFImageRep] != nil);
}
- (NSPDFImageRep * _Nullable)PDFImageRep
{
for (NSImageRep *imageRep in self.representations)
{
if ([imageRep isKindOfClass:[NSPDFImageRep class]]){
return (NSPDFImageRep*)imageRep;
}
}
return nil;
}
- (void)saveAsPDFWithOutputDirectory:(NSURL *)outputDirectory size:(NSSize)newSize
{
NSPDFImageRep *pdfRep = self.PDFImageRep;
NSMutableData *mutablePDFRef = [[NSMutableData alloc]initWithData:pdfRep.PDFRepresentation];
CFMutableDataRef pdfDataRef = (__bridge CFMutableDataRef)(mutablePDFRef);
CGRect bounds = CGRectMake(0, 0, newSize.width, newSize.height);
CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData(pdfDataRef);
CGContextRef context = CGPDFContextCreate(consumer, &bounds, nil);
CGPDFContextBeginPage(context, NULL);
NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:gc];
[self drawInRect:NSMakeRect(0, 0, newSize.width, newSize.height)];
[NSGraphicsContext restoreGraphicsState];
CGPDFContextEndPage(context);
CGPDFContextClose(context);
CGContextRelease(context);
CGDataConsumerRelease(consumer);
NSError *error = nil;
NSData *pdfData = (__bridge NSData *)(pdfDataRef);
[pdfData writeToURL:outputDirectory options:NSDataWritingAtomic error:&error];
if (error)
{
NSLog(@"Error saving image: %@", error);
}
}