I want to add a transparent overlay to an image
The code I am using it :
- (UIImage *) overlayImage
{
VampirizerAppDelegate* app = (VampirizerAppDelegate *)[UIApplication sharedApplication].delegate;
UIImage* pSourceImage;
pSourceImage = pTempResult;
UIImage *topOverlayImg = [UIImage imageNamed:#"overlay-disco-lights-top.png"];
// size is taken from the background image
UIGraphicsBeginImageContext(pSourceImage.size);
[pSourceImage drawAtPoint:CGPointZero];
CGRect topImageRect = CGRectMake(0, 0, pSourceImage.size.width, pSourceImage.size.height);
[pSourceImage drawInRect:topImageRect blendMode:kCGBlendModeOverlay alpha:0.99];
NSLog(#"topImageRect : %#", NSStringFromCGRect(topImageRect));
UIImage *combinedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return combinedImage;
}
the problem is that the final image I am getting is not clear and is distorted.
Please help
Related
When you use .imageView.adjustsImageWhenAncestorFocused you get your image scaled, you get it bigger on focus. The image goes beyond it's bounds. That means that you can't see full image - it's coped on all sides.
You have:
You want:
If you want it work from the box, you need to remember to reserve Focused/Safe zone size (from documentation) when you create your image.
In my case I have my images from server and I can't edit them.
What worked for me - it's to redraw image right before setting:
UIImage *oldImage = [UIImage imageNamed:#"example"];
CGFloat width = cell.imageView.frame.size.width;
CGFloat height = cell.imageView.frame.size.height;
CGSize newSize = CGSizeMake(width, height);
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGImageRef imageRef = oldImage.CGImage;
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
CGContextRef resizeContext = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(resizeContext, kCGInterpolationHigh);
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);
CGContextConcatCTM(resizeContext, flipVertical);
CGContextDrawImage(resizeContext, newRect, imageRef);
CGImageRef newImageRef = CGBitmapContextCreateImage(resizeContext);
UIImage *newImageResized = [UIImage imageWithCGImage:newImageRef];
CGImageRelease(newImageRef);
UIGraphicsEndImageContext();
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = newImageResized;
});
It's nor necessary to redraw in this way, but the point is you need to draw your UIImage again in order to have your image displayed properly.
Code from here.
I am making an application using Box2D in which i am getting images from Asset Library and displaying them as sprites.
here is the code which i have done :
Getting Images from asset library :
CGImageRef imgRef = [[mutArrAssetPhotos objectAtIndex:i] thumbnail];
Creating Texture2D :
CCTexture2D *spriteTexture = [[CCTexture2D alloc]initWithCGImage:imgRef resolutionType:kCCResolutionUnknown];
Creating sprites from textures :
CCSprite *paddle = [CCSprite spriteWithTexture:spriteTexture];
This gives me warning in console like :
"cocos2d: CCTexture2D: Using RGB565 texture since image has no alpha"
Still in simulator it works fine though warning but in device images are not being displayed.
But instead if i used :
CCSprite *paddle = [CCSprite spriteWithFile:#"img.png"];
it is working fine and is not giving any warning also.
Can anyone help please ?? Thanks in Advance.
I've solved it.
Somehow i managed to recreate the image, from which i was creating sprite.
CGImageRef imgRef = [[mutArrAssetPhotos objectAtIndex:i] thumbnail];
UIImage *image = [self updateImage:[UIImage imageWithCGImage:imgRef]];
imgRef = image.CGImage;
CCSprite *paddle = [CCSprite spriteWithCGImage:image.CGImage key:[NSString stringWithFormat:#"%d",i]];
And for updating the image, i redraw it so that i do not get any alpha warnings.The update method is like this :
-(UIImage *) updateImage:(UIImage *)image
{
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.frame = CGRectMake(0,50, image.size.width,image.size.height);
image = [self captureImageFrom:imgView];
[imgView release];
return image;
}
-(UIImage *) captureImageFrom:(UIImageView *)view{
UIGraphicsBeginImageContext(view.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenShot;
}
I think (could not find docs to confirm tough) that the thumbnail changes the image format so you get a plain no alpha image ref.
Try using the following for creating the right image ref :
CGImageRef imgRef = [[[mutArrAssetPhotos objectAtIndex:i] defaultRepresentation] fullResolutionImage];
Let me tell you about the problem I am having and how I tried to solve it. I have a UIScrollView which loads subviews as one scrolls from left to right. Each subview has 10-20 images around 400x200 each. When I scroll from view to view, I experience quite a bit of lag.
After investigating, I discovered that after unloading all the views and trying it again, the lag was gone. I figured that the synchronous caching of the images was the cause of the lag. So I created a subclass of UIImageView which loaded the images asynchronously. The loading code looks like the following (self.dispatchQueue returns a serial dispatch queue).
- (void)loadImageNamed:(NSString *)name {
dispatch_async(self.dispatchQueue, ^{
UIImage *image = [UIImage imageNamed:name];
dispatch_sync(dispatch_get_main_queue(), ^{
self.image = image;
});
});
}
However, after changing all of my UIImageViews to this subclass, I still experienced lag (I'm not sure if it was lessened or not). I boiled down the cause of the problem to self.image = image;. Why is this causing so much lag (but only on the first load)?
Please help me. =(
EDIT 3: iOS 15 now offers UIImage.prepareForDisplay(completionHandler:).
image.prepareForDisplay { decodedImage in
imageView.image = decodedImage
}
or
imageView.image = await image.byPreparingForDisplay()
EDIT 2: Here is a Swift version that contains a few improvements. (Untested.)
https://gist.github.com/fumoboy007/d869e66ad0466a9c246d
EDIT: Actually, I believe all that is necessary is the following. (Untested.)
- (void)loadImageNamed:(NSString *)name {
dispatch_async(self.dispatchQueue, ^{
// Determine path to image depending on scale of device's screen,
// fallback to 1x if 2x is not available
NSString *pathTo1xImage = [[NSBundle mainBundle] pathForResource:name ofType:#"png"];
NSString *pathTo2xImage = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:#"#2x"] ofType:#"png"];
NSString *pathToImage = ([UIScreen mainScreen].scale == 1 || !pathTo2xImage) ? pathTo1xImage : pathTo2xImage;
UIImage *image = [[UIImage alloc] initWithContentsOfFile:pathToImage];
// Decompress image
if (image) {
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
[image drawAtPoint:CGPointZero];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
// Configure the UI with pre-decompressed UIImage
dispatch_async(dispatch_get_main_queue(), ^{
self.image = image;
});
});
}
ORIGINAL ANSWER: It turns out that it wasn't self.image = image; directly. The UIImage image loading methods don't decompress and process the image data right away; they do it when the view refreshes its display. So the solution was to go a level lower to Core Graphics and decompress and process the image data myself. The new code looks like the following.
- (void)loadImageNamed:(NSString *)name {
dispatch_async(self.dispatchQueue, ^{
// Determine path to image depending on scale of device's screen,
// fallback to 1x if 2x is not available
NSString *pathTo1xImage = [[NSBundle mainBundle] pathForResource:name ofType:#"png"];
NSString *pathTo2xImage = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:#"#2x"] ofType:#"png"];
NSString *pathToImage = ([UIScreen mainScreen].scale == 1 || !pathTo2xImage) ? pathTo1xImage : pathTo2xImage;
UIImage *uiImage = nil;
if (pathToImage) {
// Load the image
CGDataProviderRef imageDataProvider = CGDataProviderCreateWithFilename([pathToImage fileSystemRepresentation]);
CGImageRef image = CGImageCreateWithPNGDataProvider(imageDataProvider, NULL, NO, kCGRenderingIntentDefault);
// Create a bitmap context from the image's specifications
// (Note: We need to specify kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little
// because PNGs are optimized by Xcode this way.)
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContext = CGBitmapContextCreate(NULL, CGImageGetWidth(image), CGImageGetHeight(image), CGImageGetBitsPerComponent(image), CGImageGetWidth(image) * 4, colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
// Draw the image into the bitmap context
CGContextDrawImage(bitmapContext, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
// Extract the decompressed image
CGImageRef decompressedImage = CGBitmapContextCreateImage(bitmapContext);
// Create a UIImage
uiImage = [[UIImage alloc] initWithCGImage:decompressedImage];
// Release everything
CGImageRelease(decompressedImage);
CGContextRelease(bitmapContext);
CGColorSpaceRelease(colorSpace);
CGImageRelease(image);
CGDataProviderRelease(imageDataProvider);
}
// Configure the UI with pre-decompressed UIImage
dispatch_async(dispatch_get_main_queue(), ^{
self.image = uiImage;
});
});
}
I think, the problem could be Images themselves. For example - I got in one of my projects 10 images 640x600 layered with alpha transparency on each other. When I try to push or pop viewcontroller from this viewcontroller.. it lags a lot.
when I leave only few images or use quite smaller images - no lag.
P.S. tested on sdk 4.2 ios5 iphone 4.
Herer is my resize routine...
in the line CGContextDrawImage the app crashes after 2 or 3 calls of the routine.
there is no memory warning or something.
it just chrashes
- (UIImage *)resizedImage:(CGSize)newSize
transform:(CGAffineTransform)transform
drawTransposed:(BOOL)transpose
interpolationQuality:(CGInterpolationQuality)quality {
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGRect transposedRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width);
CGImageRef imageRef = self.CGImage;
// Build a context that's the same dimensions as the new size
CGContextRef bitmap = CGBitmapContextCreate(NULL,
newRect.size.width,
newRect.size.height,
CGImageGetBitsPerComponent(imageRef),
0,
CGImageGetColorSpace(imageRef),
CGImageGetBitmapInfo(imageRef));
// Rotate and/or flip the image if required by its orientation
CGContextConcatCTM(bitmap, transform);
// Set the quality level to use when rescaling
CGContextSetInterpolationQuality(bitmap, quality);
// Draw into the context; this scales the image
////////////AFTER THAT IT CRASHS!!!
CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef);
// Get the resized image from the context and a UIImage
CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
// Clean up
CGContextRelease(bitmap);
CGImageRelease(newImageRef);
return newImage;
}
someone a hint?
regards, phil
Maybe you should add autorelease pool or #autorelease{} for ARC?
I think, it would help.
I have an NSImage which I am trying to resize like so;
NSImage *capturePreviewFill = [[NSImage alloc] initWithData:previewData];
NSSize newSize;
newSize.height = 160;
newSize.width = 120;
[capturePreviewFill setScalesWhenResized:YES];
[capturePreviewFill setSize:newSize];
NSData *resizedPreviewData = [capturePreviewFill TIFFRepresentation];
resizedCaptureImageBitmapRep = [[NSBitmapImageRep alloc] initWithData:resizedPreviewData];
saveData = [resizedCaptureImageBitmapRep representationUsingType:NSJPEGFileType properties:nil];
[saveData writeToFile:#"/Users/ricky/Desktop/Photo.jpg" atomically:YES];
My first issue is that my image gets squashed when I try to resize it and don't conform to the aspect ratio. I read that using -setScalesWhenResized would resolve this problem but it didn't.
My second issue is that when I try to write the image to a file, the image isn't actually resized at all.
Thanks in advance,
Ricky.
I found this blog post to be very helpful for resizing my image: http://weblog.scifihifi.com/2005/06/25/how-to-resize-an-nsimage/
You will need to enforce the aspect ratio on the image resizing yourself, it won't be done for you. This is how I did it when I was trying to fit the image into the printable area on the default paper:
NSImage *image = ... // get your image
NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
NSSize paperSize = printInfo.paperSize;
CGFloat usablePaperWidth = paperSize.width - printInfo.leftMargin - printInfo.rightMargin;
CGFloat resizeWidth = usablePaperWidth;
CGFloat resizeHeight = usablePaperWidth * (image.size.height / image.size.width);
Here is a slightly modified version of his code from the blog:
NSData *sourceData = [image TIFFRepresentation];
float resizeWidth = ... // your desired width;
float resizeHeight = ... // your desired height;
NSImage *sourceImage = [[NSImage alloc] initWithData: sourceData];
NSImage *resizedImage = [[NSImage alloc] initWithSize: NSMakeSize(resizeWidth, resizeHeight)];
NSSize originalSize = [sourceImage size];
[resizedImage lockFocus];
[sourceImage drawInRect: NSMakeRect(0, 0, resizeWidth, resizeHeight) fromRect: NSMakeRect(0, 0, originalSize.width, originalSize.height) operation: NSCompositeSourceOver fraction: 1.0];
[resizedImage unlockFocus];
NSData *resizedData = [resizedImage TIFFRepresentation];
[sourceImage release];
[resizedImage release];
If you can require Mac OS X 10.6 or later, send your image a CGImageForProposedRect:context:hints: message, then write the CGImage out using a CGImageDestination object.
The rectangle should have NSZeroPoint as its origin, and its size be the size you want.
This still won't scale the image proportionally (maintaining aspect ratio); you have to do that yourself.
The pre-10.6 way to do this (without going through a TIFF representation) is to lock focus on the resized image, create an NSBitmapImageRep for the extent of the image (that is, a rectangle with zero origin and the image's size), unlock focus, and then ask that bitmap image rep for JPEG data.