Difference between UIImage and UIImageView - objective-c

What is the difference between UIImage and UIImageView? Can someone explain it with an example?

Example:
UIImage *bgImage = [UIImage imageNamed:#"Default#2x.png"];
UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:bgImage];
backgroundImageView.frame = [[UIScreen mainScreen] bounds];
UIImage Overview:
A UIImage object is a high-level way to display image data. You can
create images from files, from Quartz image objects, or from raw image
data you receive. The UIImage class also offers several options for
drawing images to the current graphics context using different blend
modes and opacity values.
Image objects are immutable, so you cannot change their properties
after creation. This means that you generally specify an image’s
properties at initialization time or rely on the image’s metadata to
provide the property value. In some cases, however, the UIImage class
provides convenience methods for obtaining a copy of the image that
uses custom values for a property.
Because image objects are immutable, they also do not provide direct
access to their underlying image data. However, you can get an NSData
object containing either a PNG or JPEG representation of the image
data using the UIImagePNGRepresentation and UIImageJPEGRepresentation
functions.
The system uses image objects to represent still pictures taken with
the camera on supported devices. To take a picture, use the
UIImagePickerController class. To save a picture to the Saved Photos
album, use the UIImageWriteToSavedPhotosAlbum function.
UIImageView Overview:
An UIImageView provides a view-based container for displaying
either a single image or for animating a series of images. For
animating the images, the UIImageView class provides controls to set
the duration and frequency of the animation. You can also start and
stop the animation freely.
New image view objects are configured to disregard user events by
default. If you want to handle events in a custom subclass of
UIImageView, you must explicitly change the value of the
userInteractionEnabled property to YES after initializing the object.
When a UIImageView object displays one of its images, the actual
behavior is based on the properties of the image and the view. If
either of the image’s leftCapWidth or topCapHeight properties are
non-zero, then the image is stretched according to the values in those
properties. Otherwise, the image is scaled, sized to fit, or
positioned in the image view according to the contentMode property of
the view. It is recommended (but not required) that you use images
that are all the same size. If the images are different sizes, each
will be adjusted to fit separately based on that mode.
All images associated with a UIImageView object should use the same
scale. If your application uses images with different scales, they may
render incorrectly.

UIImage contains the data for an image.
UIImageView is a custom view meant to display the UIImage.

In short:
You create an instance of UIImage object to hold image's data, like this:
NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"/picture.jpg"]; //assuming your image is in your app's bundle
UIImage *img = [[UIImage alloc]initWithContentsOfFile:sourcePath];
You then create an instance of UIImageView either through IB or code to display your image on the screen, like this:
[imageView1 setImage:img]; //assume you already create an instance of UIImageView named imageView1

UIImage is a data object that holds image bytes.
UIImageView is a control that display UIImage data.

UIImage objects store data from an image (i.e. data from a png file)
UIImageView objects are used to display a UIImage

UIimage is an Object which stores data (Jpg, png...)
and UIImageView class which contains UIImage as a property.
UIImageView can have multiple UIImages, and UIImage is immutable.
That bothered me a long time ago, when you create an image you do:
var image: UIImageView!
But when you execute that "image" you do
image.image = UIImage.init(named: "image")
Its really easy, you use UIimageView, to create an image with UIImage.
UIImage displays the image, and UIImageView is a container for that UIImage.

UIImage holds the data as like (pictures) and displays it on UIImageView.
UIImageView is a type of container to display images.

UIImageView *myImage = [[UIImageView alloc]init];
[myImage setImage:[UIImage imageNamed:#"1.png"]];
create an instance for UIImageView as "myImage".This is helps for dispaly data.UIImage helps for hold the data of 1.png from the assets file in the xcode.

Related

using UIImageView to show correct image size

how do you use UiimageView to show an image to make sure the imageview is the correct size of the UIImage? thanks!
This code should create an imageView with the frame of your image automatically.
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"ImageName"]];
A little background from the docs.
This method adjusts the frame of the receiver to match the size of the
specified image. It also disables user interactions for the image view
by default.

Draw several UIViews on one layer

Is it possible to draw several UIViews with custom drawing on single CALayer so that they dont have backing store each?
UPDATE:
I have several uiviews of the same size which have same superview. Right now each of them has custom drawing. And because of big size they create 600-800 mb backing stores on iPad 3. so i want to compose their output on one view and have several times less memory consumed.
Every view has it's own Layer and you can't change that.
You could enable shouldRasterize to flatten a view hierarchy, which might help in some cases, but that needs gpu memory.
another way could be to create an image context and merge the drawings into the image and set that as the layer content.
in one of the wwdc session videos of last year which was about drawing showed a drawing app where many strokes were transfered into a image to speed up drawing.
Since the views will share the same backing store, I assume you want them to share the same image that results from the layer's custom drawing, right? I believe this can be done with something similar to:
// create your custom layer
MyCustomLayer* layer = [[MyCustomLayer alloc] init];
// create the custom views
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake( 0, 0, layer.frame.size.width, layer.frame.size.height)];
UIView* view2 = [[UIView alloc] initWithFrame:CGRectMake( 100, 100, layer.frame.size.width, layer.frame.size.height)];
// have the layer render itself into an image context
UIGraphicsBeginImageContext( layer.frame.size );
CGContextRef context = UIGraphicsGetCurrentContext();
[layer drawInContext:context];
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// set the backing stores (a.k.a the 'contents' property) of the view layers to the resulting image
view1.layer.contents = (id)image.CGImage;
view2.layer.contents = (id)image.CGImage;
// assuming we're in a view controller, all those views to the hierarchy
[self.view addSubview:view1];
[self.view addSubview:view2];

Show portion of UIImage in UIImageVIew

This question might have been answered, but I can't find a solution to my problem after hours of googling.
I have a UIImageView (320*320) in a custom UITableCell with a UIImage (320*320) inside.
When I click on a button, the UIImageView resizes to 320*80 (animated) and the UIImage too.
How could I do to prevent the UIImage from resizing ?
I would like this UIImage to stay but same and show only a portion of this image ( a 320*80 frame with 0/0 origin)
Edit : Cropping
I thought of cropping the image to the right size and then set the UIImageView's image to the fullsize image, but it looks ugly because when the user clicks on the UIImageView, this one is still 320*320 but the UIImage has been set to the cropped one (320*80) so it is streched...
Thanks
I'm doing something similar in one of my apps, when I create the UIImageView object, I set the property contentMode to UIViewContentModeScaleAspectFill, and the clipsToBounds property to YES. Hope this helps.
You can resize the image and then replace the UIImageView image with the resized one.
CGImageRef imageToBeResized = yourImage.CGImage;
CGImageRef partOfImageAsCG = CGImageCreateWithImageInRect(imageToBeResized, CGRectMake(0, 0, 320, 80));
CGRelease(imageToBeResized);
UIImage *resizedImage = [UIImage imageWithCGImage:imageToBeResized];
Maybe you should think about use a UIScrollView with your UIImageView inside. So, you can with its properties to archive the desired behaviour.

Overlay an UIImage above an UIImageView, possible? example code?

Is it possible to set an image over an other image,
respectively to overlay an image above an UIImage.
I give some code:
Headerfile:
#property (nonatomic,assign)UIImageView* imageView;
Implementationfile
UIImage *overlayImage = [UIImage imageNamed:#"lamp.png"];
The "imageView.image" has got an image and above that I will have this lamp, but later on it has to be possible to move it.
I searched some methods, but all methods gave me warnings.
Could you help me how to manage it? And is Core Animation an alternative to handle that?
Just add it as a subview. UIImageView is a UIView like any other.
UIImage *overlayImage = [UIImage imageNamed:#"lamp.png"];
UIImageView *overlayImageView = [[UIImageView alloc] initWithImage:overlayImage];
[self.imageView addSubview:overlayImageView];
You should use another UIImageView. A UIImage doesn't refer to an actual view in the interface, it's used as a reference to an image to be reused in code.
UIImageView* lampImageView= [[UIImageView alloc] initWithImage:overlayImage];
This way you can move it around anywhere over the first image view.

Passing UIImage to a function and Edit it externally

Let's say we have this part of code for a UIView subclass:
self.myImage = [UIImage imageNamed:#"img1.jpg"];
[self myFunc:self.myImage];
myFunc is here defined:
-(void)myFunc(UIImage*)img{
UIImageView *imgView = [[UIImageView alloc]initWithImage:img];
[self addSubview:imgView];
}
Now i show in my view img1.jpg, if i decide to change self.myImage AFTER myFunc call
self.myImage = [UIImage imageNamed:#"img2.jpg"];
why i continue to show img1 and not img2 ??? myFunc receive a UIImage pointer not directly an object... i'm pretty confused and i missed something really important i think.
Edit --
I'd like to have many UIImageView, and every image ivar of these view must pointing to the same image address, changing image at this address every UIImageView have a new image how can i do that ?
Given your code. Let say that when you load img1.jpg into memory it went to address 1000. And you use the ivar myImage to point to it. When you pass that ivar to your function and create the UIImageView it also points to img1.jpg.
Now, when you load img2.jpg into memory it went to a different address, for example 2000. And then updated the ivar myImage to point to that new location. img1.jpg is still in address 1000 and is still being used by the UIImageView.
If you want to change the image of the UIImageView you will have to use the image property of that class.
The UIImage that you've given to the UIImageView does in fact not know itself the view it belongs to. It may be used in different views. You have to ask the UIImageView object for the current image that it displays. If you want to change the displayed image you would write:
self.imgView.image = [UIImage imageNamed:#"img2.jpg"];
Better you add a property for the UIImageView so that you can access it from everywhere in the class.