Setting UIImageView with image from cache - ios

I cache an image when the user logs in like this:
This is in a Utility.m
UIImage *image = [UIImage imageWithData:newProfilePictureData];
UIImage *mediumImage = [image thumbnailImage:280 transparentBorder:0 cornerRadius:0 interpolationQuality:kCGInterpolationHigh];
UIImage *smallRoundedImage = [image thumbnailImage:64 transparentBorder:0 cornerRadius:9 interpolationQuality:kCGInterpolationLow];
NSData *mediumImageData = UIImageJPEGRepresentation(mediumImage, 0.5); // using JPEG for larger pictures
NSData *smallRoundedImageData = UIImagePNGRepresentation(smallRoundedImage);
Later on I would like to load the small image into an UIImageView:
This is in a UITableView - cellForRowAtIndexPath
[cell.leftIcon setImage:
Does anyone know how I can reference the cached image?

You need something like below method in Utility.m,
+(NSString*)getImage {
return smallRoundedImage;
}
Then use it like below,
[cell.leftIcon setImage:[Utility getImage]];
PS: This is just an example, you can make this much better based on what's your requirements!

Related

difference between UIImageView.image = ... and UIimageView.layer.content =

Two ways of set UIImage to A UIImageView:
First:
self.imageview.image = [UIImage imageNamed:#"clothing.png"];
Second:
self.imageview.layer.contents = (__bridge id _Nullable)([[UIImage imageNamed:#"clothing.png"] CGImage]);
what is the difference between the two ways?
which one is better?
In fact.What I want to do is displaying part of one PNG in UIImageView.
There are two ways:
First:
UIImage *image = [UIImage imageNamed:#"clothing.png"];
CGImageRef imageRef = CGImageCreateWithImageInRect(image, rect);
self.imageview.image = [UIImage imageWithCGImage:imageRef];
Second:
self.imageview2.layer.contents = (__bridge id _Nullable)([[UIImage imageNamed:#"clothing.png"] CGImage]);//way2
self.imageview2.layer.contentsRect = rect;
Which one is better? Why? Thanks!
First:
self.imageview.image = [UIImage imageNamed:#"clothing.png"];
By using this you can directly assign your image to any UIImageView While in
Second:
self.imageview.layer.contents = (__bridge id _Nullable)([[UIImage imageNamed:#"clothing.png"] CGImage]);
You can not assign image directly to layer. so you need to put a CGImage into a layer.
So First is best forever. Thank you.
First option is better, Bridge concept is used before introduction of ARC
Of course the better way is the first one :
self.imageview.image = [UIImage imageNamed:#"clothing.png"];
Indeed, this is the way an UIImageView is built for.
For clarification, every view (UIView, UIImageView, etc) has a .layer property to add visual content on it. Here you're adding an image in it. You could have achieved the same result with a single UIView. But, in performances terms and clarity, you should (have to) use .image property.
Edit :
Even with your new edit, first option is still the better one.
You can do that but it's your responsibility to modify the image to make the image.CGImage draw correctly respect to imageOrientation, contentMode and so on. If you set the image with imageView.image = image;, it's apple's responsibility to do that.
I give you an example that causes the problem:
as image.CGImage doesn't contain image orientation, so if you set it directly and if the source image is not UIImageOrientationUp, the image will be rotated, unless you "fix the orientation" of the source image like this. (You can get a image that is not UIImageOrientationUp, just take a photo with your iPhone)
- (UIImage *)fixOrientation {
if (self.imageOrientation == UIImageOrientationUp) return self;
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
[self drawInRect:(CGRect){0, 0, self.size}];
UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return normalizedImage;
}
Here are two screen shot, the first is set image.CGImage directly to layer.contents, the second is set image to imageView.image.
So always use imageView.image unless you know what you're doing.

How to add several UIImages to one base UIImage in iOS

I know there has to be a way to take one base image (in my case a transparent 4096x4096 base layer) and adding several dozen (up to 100) very small (100x100) images to it in different locations. BUT I cannot figure out how to do it: Assume for the following that imageArray has many elements, each containing a NSDictionary with the following structure:
#{
#"imagename":imagename,
#"x":xYDict[#"x"],
#"y":xYDict[#"y"]
}
Now, here is the code (that is not working. all I have is a transparent screen...and the performance is STILL horrible...about 1-2 seconds per "image" in the loop...and massive memory use.
NSString *PNGHeatMapPath = [[myGizmoClass dataDir] stringByAppendingPathComponent:#"HeatMap.png"];
#autoreleasepool
{
CGSize theFinalImageSize = CGSizeMake(4096, 4096);
NSLog(#"populateHeatMapJSON: creating blank image");
UIGraphicsBeginImageContextWithOptions(theFinalImageSize, NO, 0.0);
UIImage *theFinalImage = UIGraphicsGetImageFromCurrentImageContext();
for (NSDictionary *theDict in imageArray)
{
NSLog(#"populateHeatMapJSON: adding: %#",theDict[#"imagename"]);
UIImage *image = [UIImage imageNamed:theDict[#"imagename"]];
[image drawInRect:CGRectMake([theDict[#"x"] doubleValue],[theDict[#"y"] doubleValue],image.size.width,image.size.height)];
}
UIGraphicsEndImageContext();
NSData *imageData = UIImagePNGRepresentation(theFinalImage);
theFinalImage = nil;
[imageData writeToFile:PNGHeatMapPath atomically:YES];
NSLog(#"populateHeatMapJSON: PNGHeatMapPath = %#",PNGHeatMapPath);
}
I KNOW I am misunderstanding UIGraphics contexts...can someone help me out? I am trying to superimpose a bunch of UIImages on the blank transparent canvas at certain x,y locations, get the final image and save it.
PS: This is also .. if the simulator is anything to go by ... leaking like heck. It goes up to 2 or 3 gig...
Thanks in advance.
EDIT:
I did find this and tried it but it requires me to rewrite the entire image, copy that image to a new one and add to that new one. Was hoping for a "base image", "add this image", "add that image", "add the other image" and get the new base image without all the copying:
Is this as good as it gets?
+(UIImage*) drawImage:(UIImage*) fgImage
inImage:(UIImage*) bgImage
atPoint:(CGPoint) point
{
UIGraphicsBeginImageContextWithOptions(bgImage.size, FALSE, 0.0);
[bgImage drawInRect:CGRectMake( 0, 0, bgImage.size.width, bgImage.size.height)];
[fgImage drawInRect:CGRectMake( point.x, point.y, fgImage.size.width, fgImage.size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
You are getting the image UIGraphicsGetImageFromCurrentImageContext() before you have actually drawn anything. Move this call to after your loop and before the UIGraphicsEndImageContext()
Your drawing actually occurs on the line
[image drawInRect:CGRectMake([theDict[#"x"] doubleValue],[theDict[#"y"] doubleValue],image.size.width,image.size.height)];
the function UIGraphicsGetImageFromCurrentImageContext() gives you the image of the current contents of the context so you need to ensure that you have done all your drawing before you grab the image.

UITableViewCell.ImageView.image Compare UIImage

I am comparing cell.imageView.image with UIImage as below code.
Please refer below Code
UIImage *imgOne = [UIImage imageNamed:#"One"];
if([customCell.imageView.image isEqual: imgOne]){
NSLog(#"Right Image");
}
While debugging, I write as po [customCell.imageView.image isEqual imgOne], but it always returns as 'nil'.
Can anyone tell me how to compare this or proper way to compare?
Generally UIImageView can not store file name of image but it store only UIImage so, it is not possible to get file name of image which you add in UIImageView.
Thats way if you want to compare only image file name then it is not possible to compare it.
But If you want to compare two UIImage object then
UIImage *secondImage = [UIImage imageNamed:#"image.png"];
NSData *imgData1 = UIImagePNGRepresentation(self.imageView.image);
NSData *imgData2 = UIImagePNGRepresentation(secondImage);
BOOL isCompare = [imgData1 isEqualToData:imgData2];
if(isCompare)
{
NSLog(#"Image View contains image.png");
}
else
{
NSLog(#"Image View doesn't contains image.png");
}
If you matain the "image one" as a member var.(1)
And set the cell's image this value.(2)
Then you can compare using those two pointers.(3)
See this code:
//1
self.imgOne = [UIImage imageNamed:#"One"];
//2
customCell.imageView.image=self.imgOne
//3
if(customCell.imageView.image == self.imgOne)
{}
Instead of Imageview I tried with Button
And than i Check as below
if([cell.button.currentImage isEqual: [UIImage imagenamed:"Your Imagenem"]]){
NSLog(#"Right Image");
}
It works fine..
Thank you.

GPUImage output image is missing in screen capture

I am trying to capture screen portion to post image on social media.
I am using following code to capture screen.
- (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Above code is perfect for capturing screen.
Problem :
My UIView contains GPUImageView with the filtered image. When I tries to capture screen using above code, that particular portion of GPUImageView does not contains the filtered image.
I am using GPUImageSwirlFilter with the static image (no camera). I have also tried
UIImage *outImage = [swirlFilter imageFromCurrentFramebuffer]
but its not giving image.
Note : Following is working code, which gives perfect output of swirl effect, but I want same image in UIImage object.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
GPUImageSwirlFilter *swirlFilter = [GPUImageSwirlFilter alloc] init];
swirlLevel = 4;
[swirlFilter setAngle:(float)swirlLevel/10];
UIImage *inputImage = [UIImage imageNamed:gi.wordImage];
GPUImagePicture *swirlSourcePicture = [[GPUImagePicture alloc] initWithImage:inputImage];
inputImage = nil;
[swirlSourcePicture addTarget:swirlFilter];
dispatch_async(dispatch_get_main_queue(), ^{
[swirlFilter addTarget:imgSwirl];
[swirlSourcePicture processImage];
// This works perfect and I have filtered image in my imgSwirl. But I want
// filtered image in UIImage to use at different place like posting
// on social media
sharingImage = [swirlFilter imageFromCurrentFramebuffer]; // This also
// returns nothing.
});
});
1) Am I doing something wrong with GPUImage's imageFromCurrentFramebuffer ?
2) And why does screen capture code is not including GPUImageView portion in output image ?
3) How do I get filtered image in UIImage ?
First, -renderInContext: won't work with a GPUImageView, because a GPUImageView renders using OpenGL ES. -renderinContext: does not capture from CAEAGLLayers, which are used to back views presenting OpenGL ES content.
Second, you're probably getting a nil image in the latter code because you've forgotten to set -useNextFrameForImageCapture on your filter before triggering -processImage. Without that, your filter won't hang on to its backing framebuffer long enough to capture an image from it. This is due to a recent change in the way that framebuffers are handled in memory (although this change did not seem to get communicated very well).

How to get UIImage to send new image and not original image to server

The user picks an image with picker and the following code manipulates the image
UIImage *image = info[UIImagePickerControllerOriginalImage];
_imageView.image = image;
_imageView.contentMode = UIViewContentModeScaleAspectFill;
_imageView.layer.cornerRadius = 10;
_imageView.clipsToBounds = YES;
_imageView.layer.shouldRasterize = YES;
_imageView.layer.rasterizationScale = [[UIScreen mainScreen] scale];
When I send imageView to the server it is sending the original image and not the new image. I am guessing this is because UIImageView does not actually change the image but is just making on the fly visual changes to the original image.
Can someone lead me in the right direction as to either what I need to learn in order to make permanent changes to an image/create new image or is there a simple way to make these changes I've made permanent?
Thanks
I suppose you talking about getting a new image like it appear on screen (with the corner radius set etc etc) so you might want to test some like that :
UIGraphicsBeginImageContext(self.imageView.image.size);
[self.imageView drawViewHierarchyInRect:self.imageView.frame afterScreenUpdates:YES];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Resources