cocoa save CIImage as bmp file image corrupted - objective-c

On OSX 10.9.5 i'm trying to save an image grabbed with QTkit as BMP file, but the image file output is sliced (corrupted) only if i save as bmp file, like this
http://imgur.com/ZuQ0NtC
But if i save the image as TIFF or PNG file all is ok here an example
http://imgur.com/xjJNNRa
The code that i use is
-UPDATE- The image is corrupted only if i apply CIfilter on CIImage *I
CIImage *I;
I=[Video cropImg:I];
//saving to disk
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc]initWithCIImage:I];
NSImage *nsImage = [[NSImage alloc] initWithSize:rep.size];
[nsImage addRepresentation:rep];
NSData *imageData = [nsImage TIFFRepresentation];
imageData = [rep representationUsingType:NSBMPFileType properties:NULL];
if ([imageData writeToFile:targetPath atomically:NO]==NO)
{
NSLog(#"Error file");
}
If i change NSBMPFileType to NSPNGFileType the image is ok, but i need bmp file

Perhaps, you should skip the conversion to "NSImage" because the code below works for me.
I=[Video cropImg:I];
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc]initWithCIImage:I];
NSData *imageData = [rep representationUsingType:NSBMPFileType properties:NULL];
[imageData writeToURL:fileURL atomically:YES];

Related

Converting an NSBitmapImageRep to NSImage

I'm flipping between NSImage and NSBitmapImageRep(because only NSBitmapImageRep lets me find-replace colors per-pixel, but only NSImages can be used in a NSImageView/NSImageCell's setImage). I know how to convert a NSImage to a NSBitmapImageRep (using bitmap = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]]), but I can't do the opposite of that because TIFFRepresentation is read-only. So, how do I convert a NSBitmapRep to a NSImage?
With hope,
radzo73
All that I had to do to get back an NSImage from my modified NSBitmapImageRep was call one method:
NSImage *image = [[NSImage alloc] initWithSize:someSize];
[...]
NSBitmapImageRep *rawImage = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
[code that gets and sets pixels]
[image initWithCGImage:[rawImage CGImage] size:image.size]; // overwrite original NSImage with modified one

Cocoa Image Compression with NSImage

I am writing a small Mac app to resize and compress jpeg files. So far I was able to resize the image properly. But I cannot compress the image (Reduce the image quality). My code is given below.
float tmph =width2* sourceSize.height/sourceSize.width;
NSSize outputSize = NSMakeSize(width2, tmph);
NSImage *anImage = [self scaleImage:sourceImage toSize:outputSize];
//compression
//NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.5] forKey:NSImageCompressionFactor];
NSData *imageDataOut = [anImage TIFFRepresentation];
NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:imageDataOut];
NSData *dataToWrite = [rep representationUsingType:NSPNGFileType properties:nil];
//NSData *dataToWrite = [rep representationUsingType:NSPNGFileType properties:options];
[dataToWrite writeToFile:outputPath atomically:NO];
scaleImage is the function I use to resize the image. That works properly. In this code I have two lines commented. NSDictionary *options..... line and NSData *dataToWrite.... lines are the two lines I added to get the compression. However with and without those two lines, I get the same size of files.
How can I get this working? Any advice?
You are setting the format type to NSPNGFileType. If you want to compress your image with JPEG, set it to NSJPEGFileType like the following.
NSData *imageDataOut = = [sourceImage TIFFRepresentation];
NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:imageDataOut];
NSDictionary *options = = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.5] forKey:NSImageCompressionFactor];
imageDataOut = [rep representationUsingType:NSJPEGFileType properties:options];
[imageDataOut writeToFile:exportpath atomically:YES];

Using NSAffineTransform to rotate NSImage results in a file twice the size

I'm using the following code to flip (rotate by 180 degrees) an NSImage.
But the new image is twice the size (MBs, not dimensions) of the original when saved to disk. I want it to be approximately the same as the original. How can I accomplish this?
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:[[_imageView image] TIFFRepresentation]];
NSImage *img = [[NSImage alloc] initWithSize:NSMakeSize(imageRep.pixelsWide, imageRep.pixelsHigh)];
[img lockFocus];
NSAffineTransform *rotator = [NSAffineTransform transform];
[rotator translateXBy:imageRep.pixelsWide yBy:imageRep.pixelsHigh];
[rotator scaleXBy:-1 yBy:-1];
[rotator concat];
[imageRep drawInRect:NSMakeRect(0, 0, imageRep.pixelsWide, imageRep.pixelsHigh)];
[img unlockFocus];
Code I'm using to save image to disk :
[[NSFileManager defaultManager] createFileAtPath:path contents:[img TIFFRepresentation] attributes:nil];
Thanks in advance!
I still don't know the root cause of this, but one work around is to save to the JPEG representation instead of the TIFF. The method I wrote is as follows :
- (void)CompressAndSaveImg:(NSImage *)img ToDiskAt:(NSString *)path WithCompressionFactor:(float)value{
NSData *imgData = [img TIFFRepresentation];
NSBitmapImageRep *imgRep = [NSBitmapImageRep imageRepWithData:imgData];
NSNumber *compressionFactor = [NSNumber numberWithFloat:value];
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:compressionFactor forKey:NSImageCompressionFactor];
imgData = [imgRep representationUsingType:NSJPEGFileType properties:imageProps];
[imgData writeToFile:path atomically:YES];
}
You can play around the with the WithCompressionFactor:(float)value parameter, but 0.75 works fine for me.

OS X - How to save NSImage or NSBitmapImageRep to PNG file without alpha channel?

I'm building an OS X app that needs to save the file to disk.
I'm currently using NSBitmapImageRep to represent the image in my code, and while saving the image to disk with representationUsingType:properties: method, I want to set the hasAlpha channel for the image, but the properties dictionary does not seem to support this.
So, I've tried to create a no-alpha bitmap representation, but according to many SO questions, the 3 channel/24 bits combination is not supported. Well, what should I do then?
Big thanks!
First off, I would try just making sure you create your NSBitmapImageRep with
-initWithBitmapDataPlanes:... hasAlpha:NO ...
And write it out and see if it the result doesn’t have alpha—one would kind of hope so.
If you’re trying to write out an image that has alpha, but not write the alpha, just copy it into a non-alpha image first, and write that out.
`
NSURL *url = [NSURL fileURLWithPath:name];
CGImageSourceRef source;
NSImage *srcImage =[[NSImage alloc] initWithContentsOfURL:url];;
NSLog(#"URL: %#",url);
source = CGImageSourceCreateWithData((__bridge CFDataRef)[srcImage TIFFRepresentation], NULL);
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, 0, NULL);
CGRect rect = CGRectMake(0.f, 0.f, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));
CGContextRef bitmapContext = CGBitmapContextCreate(NULL,
rect.size.width,
rect.size.height,
CGImageGetBitsPerComponent(imageRef),
CGImageGetBytesPerRow(imageRef),
CGImageGetColorSpace(imageRef),
kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Little
);
CGContextDrawImage(bitmapContext, rect, imageRef);
CGImageRef decompressedImageRef = CGBitmapContextCreateImage(bitmapContext);
NSImage *finalImage = [[NSImage alloc] initWithCGImage:decompressedImageRef size:NSZeroSize];
NSData *imageData = [finalImage TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.9] forKey:NSImageCompressionFactor];
imageData = [imageRep representationUsingType:NSPNGFileType properties:imageProps];
[imageData writeToFile:name atomically:NO];
CGImageRelease(decompressedImageRef);
CGContextRelease(bitmapContext);
`
ref:
https://github.com/bpolat/Alpha-Channel-Remover

Retina display problems when working with images

I have met problems when working on retina display. NSImage size is correct, but if I create NSBitmapImageRep from it and write it to file I get image witch's size is twice as big as original image. There is no such problem when I use it on non retina display.
I create NSImage from file (1920x1080)
I do some drawings on
I create NSBitmapImageRep from image with drawings
I write it to file
I get image with 3840x2160 dimensions
What could cause that?
NSImage *originalImage = [[NSImage alloc] initWithContentsOfURL:fileUrl];
NSImage *editedImage = [[NSImage alloc] initWithSize:originalImage.size];
[editedImage lockFocus];
//I draw here NSBezierPaths
[editedImage unlockFocus];
NSBitmapImageRep *savingRep = [NSBitmapImageRep imageRepsWithData:[editedImage TIFFRepresentation]];
NSData *savingData = [savingRep representationUsingType: NSPNGFileType properties: nil];
[savingData writeToFile:desiredFileLocationAndName atomically:no];
If I open image and save it without editing I get the correct dimensions image
NSImage *imageFromFile = [[NSImage alloc] initWithContentsOfURL:fileURL];
NSBitmapImageRep *newRepresentation = [[NSBitmapImageRep imageRepsWithData:[imageFromFile TIFFRepresentation]];
NSData *savingData = [newRepresentation representationUsingType: NSPNGFileType properties: nil];
[savingData writeToFile:desiredFileLocationAndName atomically:no];
A bitmap representation of the image is measured in pixels. It is twice the size. The NSImage is giving you a size in points which on retina devices measure 2 pixels per point. There is nothing wrong with what its giving you.