I've been using quartz to mask part of a screen capture, and on my iPod Touch it works fine, however on the simulator the image never gets masked.
What I'm doing is taking a screenshot, cropping the section I want to mask out, shrinking it to the size of the mask, then calling a function which applies the mask. On the iPod it works, on the simulator it does all the cropping and scaling, but not the clipping to mask.
I'm mainly concerned because I only have the one iPod Touch to test on, and I don't want it to work on other devices the way it works on the simulator.
I'm supplying the code that does the clipping, as well as the code that calls the clipping function in the hope that someone can tell me why it works differently on the device than on the simulator
Code:
- (UIImage *)clipImage:(UIImage *)imageIn withMask:(UIImage *)maskIn atRect:(CGRect) maskRect
{
//Begin the drawing context
UIGraphicsBeginImageContext(maskRect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
// Create the masked clipping region
CGContextClipToMask(ctx, maskRect, maskIn.CGImage);
// Compensate for inverted coordinate system
CGContextTranslateCTM(ctx, 0.0, maskRect.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
// Draw into context
CGContextDrawImage(ctx, CGRectMake(0, 0, imageIn.size.width, imageIn.size.height), imageIn.CGImage);
// Get the image and end the context
imageIn = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageIn;
}
- (void)doClip:(id)sender
{
//load the mask image
UIImage* mask1 = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"mask1.png"]];
//captue screen
UIImage* screenCap = [self captureView:[theDelegate window]];
//crop area we want to apply the mask to
screenCap = [UIImage imageWithCGImage:CGImageCreateWithImageInRect([screenCap CGImage],CGRectMake(10, 25, 300, 300))];
//shrink it to the size of the mask
screenCap = [self imageWithImage:screenCap scaledToSize:CGSizeMake(150, 150)];
//apply the image mask
UIImage* cropped = [self clipImage:screenCap
withMask:mask1
atRect:CGRectMake(0,0,150,150)];
//trim some extra stuff off
CGImageRef finalImage = CGImageCreateWithImageInRect([cropped CGImage], CGRectMake(10, 10, 128, 128));
maskedImageView.image = [UIImage imageWithCGImage:finalImage];
}
I wouldn't use the Simulator for anything but basic evaluation. My first app worked brilliantly on the Simulator but exhibited all sorts of problems on a real iPhone. The only way to test an app properly is with ad-hoc on a real iPhone. Ignore the Simulator in general except for build warnings and errors.
I wouldn't use the Simulator for anything but basic evaluation. My first app worked brilliantly on the Simulator but exhibited all sorts of problems on a real iPhone. The only way to test an app properly is with ad-hoc on a real iPhone. Ignore the Simulator in general except for build warnings and errors.
I understand that, but as you just said, it worked BETTER on the simulator, whereas mine is working worse. And with a lack of devices to test on, I'm paranoid that something will go wrong on an older device or something.
Plus it's quicker to compile and test little stuff on the simulator (then check it all works fine on the iPod after all the little stuff is in), and it's annoying that my images won't crop as they should. Being the simulator though it IS just an annoyance and nothing more. I just hope it all works right elsewhere...
If it works 'worse' on the simulator, oh well. The real test of mettle is on a real device - and the simulator is not an 'emulator' so there are things that will appear to work well on the simulator and fail on a real iPhone. The simulator is good for testing build errors/warnings and some GUI quirks but I, as others have said, wouldn't put any faith in it as a final arbitor.
I've also noticed a difference between the simulator and the device for clipping masks. It worked in the simulator but not on the iPhone/iPod. I figured out my problem. The image I was using as a mask had a transparent background when it should have been white. Once I changed it to white, the mask worked properly on the iPhone/iPod. Maybe that's the same problem you had too.
Quote:
Originally Posted by death_au
I've been using quartz to mask part of a screen capture, and on my iPod Touch it works fine, however on the simulator the image never gets masked.
What I'm doing is taking a screenshot, cropping the section I want to mask out, shrinking it to the size of the mask, then calling a function which applies the mask. On the iPod it works, on the simulator it does all the cropping and scaling, but not the clipping to mask.
I'm mainly concerned because I only have the one iPod Touch to test on, and I don't want it to work on other devices the way it works on the simulator.
I'm supplying the code that does the clipping, as well as the code that calls the clipping function in the hope that someone can tell me why it works differently on the device than on the simulator
Code:
- (UIImage *)clipImage:(UIImage *)imageIn withMask:(UIImage *)maskIn atRect:(CGRect) maskRect
{
//Begin the drawing context
UIGraphicsBeginImageContext(maskRect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
// Create the masked clipping region
CGContextClipToMask(ctx, maskRect, maskIn.CGImage);
// Compensate for inverted coordinate system
CGContextTranslateCTM(ctx, 0.0, maskRect.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
// Draw into context
CGContextDrawImage(ctx, CGRectMake(0, 0, imageIn.size.width, imageIn.size.height), imageIn.CGImage);
// Get the image and end the context
imageIn = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageIn;
}
- (void)doClip:(id)sender
{
//load the mask image
UIImage* mask1 = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"mask1.png"]];
//captue screen
UIImage* screenCap = [self captureView:[theDelegate window]];
//crop area we want to apply the mask to
screenCap = [UIImage imageWithCGImage:CGImageCreateWithImageInRect([screenCap CGImage],CGRectMake(10, 25, 300, 300))];
//shrink it to the size of the mask
screenCap = [self imageWithImage:screenCap scaledToSize:CGSizeMake(150, 150)];
//apply the image mask
UIImage* cropped = [self clipImage:screenCap
withMask:mask1
atRect:CGRectMake(0,0,150,150)];
//trim some extra stuff off
CGImageRef finalImage = CGImageCreateWithImageInRect([cropped CGImage], CGRectMake(10, 10, 128, 128));
maskedImageView.image = [UIImage imageWithCGImage:finalImage];
}
I've also noticed a difference between the simulator and the device for clipping masks. It worked in the simulator but not on the iPhone/iPod. I figured out my problem. The image I was using as a mask had a transparent background when it should have been white. Once I changed it to white, the mask worked properly on the iPhone/iPod. Maybe that's the same problem you had too.
With OS 2.2 it seems that when neither the main image nor the mask image have a transparency layer then whether or not the clip works on device or on the simulator is variable. When the main image has a transparency layer with a pixel set as transparent and the mask image doesn't have a transparency layer but with the masked pixels coloured black it seems to work reliably on both device and on the simuator.