NSBitmapImageRep生成的BMP无法在Windows上读取

发布于 2024-11-30 20:48:21 字数 1755 浏览 1 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

生寂 2024-12-07 20:48:21

我认为您的代码失败的主要原因是您正在使用每像素 0 位创建 NSBitmapImageRep 。这意味着您的图像代表中的信息将为零。您几乎肯定需要每像素 32 位。

但是,您的代码是一种从磁盘上的图像文件获取 NSBitmapImageRep 的令人难以置信的复杂方式。你到底为什么要使用CIImage?这是一个设计用于与 Core Image 滤镜一起使用的 Core Image 对象,在这里根本没有任何意义。您应该使用 NSImageCGImageRef

你的方法的命名也很糟糕。相反,它应该命名为 +bitmapRepForImageFileAtURL: 之类的名称,以更好地指示它正在做什么。

另外,这段代码没有任何意义:

[[theBitMapToBeSaved retain] autorelease]

调用 retain 然后调用 autorelease 不会执行任何操作,因为它所做的只是增加保留计数,然后立即再次减少它。

您负责释放 theBitMapToBeSaved,因为您是使用 alloc 创建它的。由于它正在被返回,您应该对其调用autorelease。您额外的 retain 调用只会无缘无故地导致泄漏。

试试这个:

+ (NSBitmapImageRep*)bitmapRepForImageFileAtURL:(NSURL*)imageURL
{
    NSImage* image = [[[NSImage alloc] initWithContentsOfURL:imageURL] autorelease];
    return [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
}

+ (NSData*)BMPDataForImageFileAtURL:(NSURL*)imageURL
{
    NSBitmapImageRep* bitmap = [self bitmapRepForImageFileAtURL:imageURL];
    return [bitmap representationUsingType:NSBMPFileType properties:nil];
}

你真的需要回顾 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 a CIImage? That is a Core Image object designed for use with Core Image filters and makes no sense here at all. You should be using an NSImage or CGImageRef.

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:

[[theBitMapToBeSaved retain] autorelease]

Calling retain and then autorelease 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 using alloc. Since it is being returned, you should call autorelease on it. Your additional retain call just causes a leak for no reason.

Try this:

+ (NSBitmapImageRep*)bitmapRepForImageFileAtURL:(NSURL*)imageURL
{
    NSImage* image = [[[NSImage alloc] initWithContentsOfURL:imageURL] autorelease];
    return [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
}

+ (NSData*)BMPDataForImageFileAtURL:(NSURL*)imageURL
{
    NSBitmapImageRep* bitmap = [self bitmapRepForImageFileAtURL:imageURL];
    return [bitmap representationUsingType:NSBMPFileType properties:nil];
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文