Peg*_*lon 161
您可以像这样向NSImage添加类别
@interface NSImage(saveAsJpegWithName)
- (void) saveAsJpegWithName:(NSString*) fileName;
@end
@implementation NSImage(saveAsJpegWithName)
- (void) saveAsJpegWithName:(NSString*) fileName
{
// Cache the reduced image
NSData *imageData = [self TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCompressionFactor];
imageData = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];
[imageData writeToFile:fileName atomically:NO];
}
@end
Run Code Online (Sandbox Code Playgroud)
对"TIFFRepresentation"的调用至关重要,否则您可能无法获得有效图像.
gar*_*ph0 49
做这样的事情:
NSBitmapImageRep *imgRep = [[image representations] objectAtIndex: 0];
NSData *data = [imgRep representationUsingType: NSPNGFileType properties: nil];
[data writeToFile: @"/path/to/file.png" atomically: NO];
Run Code Online (Sandbox Code Playgroud)
Arv*_*vin 34
不确定你们其他人,但我更喜欢吃我完整的辣酱玉米饼馅.上面描述的内容将起作用并且没有任何问题,但我发现遗漏了一些东西.在这里,我将突出我的观察:
所以如果你想转换那个图像,你真的想要失去所有这些吗?如果您想吃饱餐,那么请继续阅读......
有时,我的意思是,有时候没有什么比好老派的发展更好了.是的,这意味着我们必须做一些工作!
让我们开始吧:
我在NSData中创建了一个类别.这些是类方法,因为您希望这些东西是线程安全的,并且没有什么比将您的东西放在堆栈上更安全.有两种类型的方法,一种用于输出非多页图像,一种用于输出多页图像.
单个图像列表: JPG,PNG,BMP,JPEG-2000
多个图像列表: PDF,GIF,TIFF
首先在内存中创建一个可变数据空间.
NSMutableData * imageData = [NSMutableData data];
Run Code Online (Sandbox Code Playgroud)
第二个获得CGImageSourceRef.听起来丑陋已经不是了.它并没有那么糟糕,让我们继续......你真的希望源图像不是表示或NSImage数据块.但是,我们确实有一个小问题.源可能不兼容,因此请确保检查UTI与CGImageSourceCopyTypeIdentifiers()中列出的UTI
一些代码:
CGImageSourceRef imageSource = nil;
if ( /* CHECK YOUR UTI HERE */ )
return CGImageSourceCreateWithURL( (CFURLRef)aURL, nil );
NSImage * anImage = [[NSImage alloc] initWithContentsOfURL:aURL];
if ( anImage )
return CGImageSourceCreateWithData( (CFDataRef)[anImage TIFFRepresentation], nil );
Run Code Online (Sandbox Code Playgroud)
等一下,为什么NSImage在那里?好吧有一些格式没有元数据,CGImageSource不支持,但这些是有效的图像.一个例子是旧式PICT图像.
现在我们有一个CGImageSourceRef,确保它不是nil然后让我们现在得到一个CGImageDestinationRef.哇所有这些参考资料都要记录下来.到目前为止我们都在2岁!
我们将使用此函数:CGImageDestinationCreateWithData()
第三个参数是要保存的图像数.对于单个图像文件,这是1,否则您只需使用以下内容:
CGImageSourceGetCount(imageSource);
第四次参议院是零.
检查你是否有这个CGImageDestinationRef,现在让我们将来自源的图像添加到它...这也将包括任何/所有元数据并保留分辨率.
对于多个图像我们循环:
for ( NSUInteger i = 0; i < count; ++i )
CGImageDestinationAddImageFromSource( imageDest, imageSource, i, nil );
Run Code Online (Sandbox Code Playgroud)
对于单个图像,它是索引0处的一行代码:
CGImageDestinationAddImageFromSource( imageDest, imageSource, 0, nil);
Run Code Online (Sandbox Code Playgroud)
好的,最终确定它将其写入磁盘或数据容器:
CGImageDestinationFinalize( imageDest );
Run Code Online (Sandbox Code Playgroud)
因此,Mutable Data从一开始就拥有我们所有的图像数据和元数据.
我们完成了吗?几乎,即使有垃圾收集你也要清理!记住两个Ref的一个用于源,一个用于目的地,所以做一个CFRelease()
现在我们已经完成了,你最终得到的是一个保留所有元数据,分辨率等的转换后的图像......
我的NSData类别方法如下所示:
+ (NSData *) JPGDataFromURL:(NSURL *)aURL;
+ (NSData *) PNGDataFromURL:(NSURL *)aURL;
+ (NSData *) BMPDataFromURL:(NSURL *)aURL;
+ (NSData *) JPG2DataFromURL:(NSURL *)aURL;
+ (NSData *) PDFDataFromURL:(NSURL *)aURL;
+ (NSData *) GIFDataFromURL:(NSURL *)aURL;
+ (NSData *) TIFFDataFromURL:(NSURL *)aURL;
Run Code Online (Sandbox Code Playgroud)
如何调整大小或ICO/ICNS?这是另一天,但总的来说,你首先要解决大小调整...
冲洗并重复嵌入源中的多个图像.
ICO和ICNS之间的唯一区别是,一个是单个图像,而另一个是一个文件中的多个图像.打赌你猜猜哪个是哪个?!;-)对于这些格式,您必须调整大小到特定大小,否则将发生ERROR.虽然这个过程与使用正确的UTI完全相同,但调整大小更严格一些.
好的希望这可以帮助其他人,你就像我现在一样充实!
奥普斯,忘了提.当您获得NSData对象时,可以根据需要执行writeToFile,writeToURL或heck,如果需要,可以创建另一个NSImage.
快乐的编码!
neo*_*eye 14
import AppKit
extension NSImage {
@discardableResult
func saveAsPNG(url: URL) -> Bool {
guard let tiffData = self.tiffRepresentation else {
print("failed to get tiffRepresentation. url: \(url)")
return false
}
let imageRep = NSBitmapImageRep(data: tiffData)
guard let imageData = imageRep?.representation(using: .PNG, properties: [:]) else {
print("failed to get PNG representation. url: \(url)")
return false
}
do {
try imageData.write(to: url)
return true
} catch {
print("failed to write to disk. url: \(url)")
return false
}
}
}
Run Code Online (Sandbox Code Playgroud)
Cha*_*tas 12
Swift 4.2解决方案
public extension NSImage {
public func writePNG(toURL url: URL) {
guard let data = tiffRepresentation,
let rep = NSBitmapImageRep(data: data),
let imgData = rep.representation(using: .png, properties: [.compressionFactor : NSNumber(floatLiteral: 1.0)]) else {
Swift.print("\(self) Error Function '\(#function)' Line: \(#line) No tiff rep found for image writing to \(url)")
return
}
do {
try imgData.write(to: url)
}catch let error {
Swift.print("\(self) Error Function '\(#function)' Line: \(#line) \(error.localizedDescription)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特风格:
if let imgRep = image?.representations[0] as? NSBitmapImageRep
{
if let data = imgRep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: [:])
{
data.writeToFile("/path/to/file.png", atomically: false)
}
}
Run Code Online (Sandbox Code Playgroud)