NSBitmapImageRep生成的BMP无法在Windows上读取
我有一个 NSBitmapImageRep,我按以下方式创建:
+ (NSBitmapImageRep *)bitmapRepOfImage:(NSURL *)imageURL {
CIImage *anImage = [CIImage imageWithContentsOfURL:imageURL];
CGRect outputExtent = [anImage extent];
NSBitmapImageRep *theBitMapToBeSaved = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL pixelsWide:outputExtent.size.width
pixelsHigh:outputExtent.size.height bitsPerSample:8 samplesPerPixel:4
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:0 bitsPerPixel:0];
NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:theBitMapToBeSaved];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext: nsContext];
CGPoint p = CGPointMake(0.0, 0.0);
[[nsContext CIContext] drawImage:anImage atPoint:p fromRect:outputExtent];
[NSGraphicsContext restoreGraphicsState];
return [[theBitMapToBeSaved retain] autorelease];
}
并以这种方式保存为 BMP:
NSBitmapImageRep *original = [imageTools bitmapRepOfImage:fileURL];
NSData *converted = [original representationUsingType:NSBMPFileType properties:nil];
[converted writeToFile:filePath atomically:YES];
这里的问题是,BMP 文件可以在 Mac OSX 下正确读取和操作,但在 Windows 下,它只是无法加载,就像在此屏幕截图中:
屏幕截图http://dl.dropbox.com/u/1661304/Grab/74a6dadb770654213cdd9290f0131880.png
如果文件是用 MS Paint 打开的(是的,MS Paint 可以打开它)然后重新保存,那么它就会工作。
非常感谢这里的帮助。 :)
提前致谢。
I have an NSBitmapImageRep that I am creating the following way:
+ (NSBitmapImageRep *)bitmapRepOfImage:(NSURL *)imageURL {
CIImage *anImage = [CIImage imageWithContentsOfURL:imageURL];
CGRect outputExtent = [anImage extent];
NSBitmapImageRep *theBitMapToBeSaved = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL pixelsWide:outputExtent.size.width
pixelsHigh:outputExtent.size.height bitsPerSample:8 samplesPerPixel:4
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:0 bitsPerPixel:0];
NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:theBitMapToBeSaved];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext: nsContext];
CGPoint p = CGPointMake(0.0, 0.0);
[[nsContext CIContext] drawImage:anImage atPoint:p fromRect:outputExtent];
[NSGraphicsContext restoreGraphicsState];
return [[theBitMapToBeSaved retain] autorelease];
}
And being saved as BMP this way:
NSBitmapImageRep *original = [imageTools bitmapRepOfImage:fileURL];
NSData *converted = [original representationUsingType:NSBMPFileType properties:nil];
[converted writeToFile:filePath atomically:YES];
The thing here is that the BMP file can be read and manipulated correctly under Mac OSX, but under Windows, it just fails to load, just like in this screenshot:
screenshot http://dl.dropbox.com/u/1661304/Grab/74a6dadb770654213cdd9290f0131880.png
If the file is opened with MS Paint (yes, MS Paint can open it) and then resaved, though, it will work.
Would appreciate a hand here. :)
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您的代码失败的主要原因是您正在使用每像素 0 位创建
NSBitmapImageRep
。这意味着您的图像代表中的信息将为零。您几乎肯定需要每像素 32 位。但是,您的代码是一种从磁盘上的图像文件获取
NSBitmapImageRep
的令人难以置信的复杂方式。你到底为什么要使用CIImage
?这是一个设计用于与 Core Image 滤镜一起使用的 Core Image 对象,在这里根本没有任何意义。您应该使用NSImage
或CGImageRef
。你的方法的命名也很糟糕。相反,它应该命名为
+bitmapRepForImageFileAtURL:
之类的名称,以更好地指示它正在做什么。另外,这段代码没有任何意义:
调用
retain
然后调用autorelease
不会执行任何操作,因为它所做的只是增加保留计数,然后立即再次减少它。您负责释放
theBitMapToBeSaved
,因为您是使用alloc
创建它的。由于它正在被返回,您应该对其调用autorelease
。您额外的retain
调用只会无缘无故地导致泄漏。试试这个:
你真的需要回顾 Cocoa绘图指南和内存管理指南,因为看起来您在一些基本概念上遇到困难。
I think the main reason your code is failing is that you are creating your
NSBitmapImageRep
with 0 bits per pixel. That means your image rep will have precisely zero information in it. You almost certainly want 32 bits per pixel.However, your code is an unbelievably convoluted way to obtain an
NSBitmapImageRep
from an image file on disk. Why on earth are you using aCIImage
? That is a Core Image object designed for use with Core Image filters and makes no sense here at all. You should be using anNSImage
orCGImageRef
.Your method is also poorly named. It should instead be named something like
+bitmapRepForImageFileAtURL:
to better indicate what it is doing.Also, this code makes no sense:
Calling
retain
and thenautorelease
does nothing, because all it does in increment the retain count and then decrement it again immediately.You are responsible for releasing
theBitMapToBeSaved
because you created it usingalloc
. Since it is being returned, you should callautorelease
on it. Your additionalretain
call just causes a leak for no reason.Try this:
You really need to review the Cocoa Drawing Guide and the Memory Management Guidelines, because it appears that you are having trouble with some basic concepts.