如何将 NSImage 转换为 NSBitmapImageRep?我有代码:
- (NSBitmapImageRep *)bitmapImageRepresentation
{
NSBitmapImageRep *ret = (NSBitmapImageRep *)[self representations];
if(![ret isKindOfClass:[NSBitmapImageRep class]])
{
ret = nil;
for(NSBitmapImageRep *rep in [self representations])
if([rep isKindOfClass:[NSBitmapImageRep class]])
{
ret = rep;
break;
}
}
if(ret == nil)
{
NSSize size = [self size];
size_t width = size.width;
size_t height = size.height;
size_t bitsPerComp = 32;
size_t bytesPerPixel = (bitsPerComp / CHAR_BIT) * 4;
size_t bytesPerRow = bytesPerPixel * width;
size_t totalBytes = height * bytesPerRow;
NSMutableData *data = [NSMutableData dataWithBytesNoCopy:calloc(totalBytes, 1) length:totalBytes freeWhenDone:YES];
CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGContextRef ctx = CGBitmapContextCreate([data mutableBytes], width, height, bitsPerComp, bytesPerRow, CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), kCGBitmapFloatComponents | kCGImageAlphaPremultipliedLast);
if(ctx != NULL)
{
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:[self isFlipped]]];
[self drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
[NSGraphicsContext restoreGraphicsState];
CGImageRef img = CGBitmapContextCreateImage(ctx);
ret = [[NSBitmapImageRep alloc] initWithCGImage:img];
[self addRepresentation:ret];
CFRelease(img);
CFRelease(space);
CGContextRelease(ctx);
}
}
return ret;
}
它可以工作,但会导致内存泄漏。至少当我将它与 ARC 一起使用时是这样。使用initWithData:[nsimagename TIFFRepresentation]
它无法正常工作。有些图像的表现效果不好。我认为这取决于图像的格式和色彩空间。还有其他方法可以实现这一目标吗?
结果与mrwalker建议的解决方案:
Original image:
Converted to bitmapimagerep and back to image 1 time:
Converted to bitmapimagerep and back to image 3 times:
如您所见,转换为 NSBitmapImageRep 后图像每次都会变暗
@Julius:您的代码太复杂并且包含多个错误。我将仅对第一行进行更正:
- (NSBitmapImageRep *)bitmapImageRepresentation
{
for( NSImageRep *rep in [self representations] )
if( [rep isKindOfClass:[NSBitmapImageRep class]] ) return rep;
return nil;
}
这将提取第一个NSBitmapImageRep
如果它是表示中的成员,或者将返回 nil,如果没有NSBitmapImageRep
。我会给你另一个解决方案,它总是有效的NSImageReps
在陈述中:NSBitmapImageRep
, NSPDFImageRep
or NSCGImageSnapshotRep
or ...
- (NSBitmapImageRep *)bitmapImageRepresentation
{
CGImageRef CGImage = [self CGImageForProposedRect:nil context:nil hints:nil];
return [[[NSBitmapImageRep alloc] initWithCGImage:CGImage] autorelease];
}
或者为了避免 NSImage 的子类化,您可以编写:
NSImage *img = [[[NSImage alloc] initWithContentsOfFile:filename] autorelease];
CGImageRef CGImage = [img CGImageForProposedRect:nil context:nil hints:nil];
NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithCGImage:CGImage] autorelease];
这只会返回一个NSBitmapImageRep
如果图像包含多个表示(例如,很多NSBitmapImageRep
来自 TIFF 文件)。但添加一些代码很简单。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)