Add stylish frames to your photos in iPhone

Swarnendu De November 7, 2013

[UPDATES]

1. Support for both retina and non-retina device.
2. Support for higher resolution overlay .png image for  border/frame.

———————————————————————————————————————————————————————

Here I am going to explain how to play with filters in Objective C and add preset stylish borders dynamically to any UIImage.We are going to take an image and add preset stylish frames on it.In this demo project I have used four buttons showing some preset frames, clicking on which the main image gets edited with a stylish border around it. We are going to learn about

  • Core Image or CIImage
  • CIFilters
  • CIContext

At the end of the tutorial you will be able to get an app that functions like this ( see illustration 1 ) :

reqdImage
illustration 1

[button link=”http://www.youtube.com/watch?v=YDt-TIR_jDA&feature=youtu.be” linking=”new-window” size=”medium” type=”simple” title=”Mosaic Image Gallery with Sencha Touch”]Demo[/button]    [button link=”https://github.com/innofied/photoframing” linking=”new-window” size=”medium” type=”simple” title=”Download” label=”Download”]Download[/button]
Before we get started, let’s discuss some of the most important classes in the Core Image framework:

  • CIContext: All of the processing of a core image is done in a CIContext. This is somewhat similar to a Core Graphics or OpenGL context.
  • CIImage :  This class hold the image data. It can be creating from a UIImage, from an image file, or from pixel data.
  • CIFilter:  The filter class has a dictionary that defines the attributes of the particular filter that it represents. Examples of filters are vibrance filters, color inversion filters, cropping filters, and much more.

For more detail please visit Apple Developer documentation on Core Image.

The Tutorial Project

Open a new project in Xcode (am using Xcode 5.0) and go to storyboard (available from and above Xcode 4.0). As you have seen I prefer using storyboard most of the time, since it is easier to handle, and faster than coding. Lets make the storyboard ready for coding process.

Before editing the storyboard include the border Images you want to apply in your project by simply dragging in and dropping them in project navigation pane(left pane) of you Xcode or you can right click and add files to your directory. I have used four borders in this demo project. You can download this from here . You can also create your new stylish borders using any image manipulation software. Keep in mind the border images must be in .png format. I have used square borders of size 320×320 for this demo purpose. Also add another Image to the project. This will be the image on which we are making the change. Here I have used a 320x 320 image. This image can be of any file type.

Steps to Follow In storyboard

  • Take an UIImageView and set it on top of the screen to display the image that is to be edited. We will update this imageView to show the final image after editing
  • Take four Buttons and place them at the bottom.
  • Change the background Image of buttons with the border images.
  • Your storyboard now looks like this: (see illustration 2)

finalScreen

Coding

Open the assistant editor mode of Xcode which brings your respective viewcontroller.m file beside your storyboard. Perform the following actions:

  • Open the viewController.m file.
  • Ctrl-Drag and drop one IBOutlet of the UIImageView in your .m file and set its property as imageView. And synthesize it. Use this code in your interface
    @property (weak, nonatomic) IBOutlet UIImageView *imageView;

    and synthesize it using

    @synthesize imageView;
  •  Similarly Ctrl-Drag all the UIButtons and create outlets for each and synthesize them. In the end your code must look like this:
    @property (weak, nonatomic) IBOutlet UIButton *border1;
    @property (weak, nonatomic) IBOutlet UIButton *border2;
    @property (weak, nonatomic) IBOutlet UIButton *border3;
    @property (weak, nonatomic) IBOutlet UIButton *border4;

    and

    @synthesize border1, border2, border3,border4;
  • Set the source image in viewDidLoad. Also create tags for different border buttons here. Use this code :
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    	// Do any additional setup after loading the view, typically from a nib.
        border1.tag =1;
        border2.tag =2;
        border3.tag =3;
        border4.tag =4;
        imageView.image = [UIImage imageNamed:@"car.png"];
    }

    Here, the imageView is set with a image named car.png, this image can be of any file type, jpg, JPG, JPEG, etc. The border buttons are tagged serially form the left.

  • Ctrl-Drag one IBAction from a button in storyboard in the implementation part of the code in .m file. Choose sender type as UIButton instead of id
  • Ctrl-Drag from other buttons to this IBAction method.
  • Paste the code in the method
    - (IBAction)borderButtonTapped:(UIButton *)sender {
    
        imageView.image = [UIImage imageNamed:@"car.png"];
    
        UIImage *borderImage = [UIImage imageNamed:[NSString stringWithFormat:@"borderImage%i.png", sender.tag]];
    
        NSData *dataFromImage = UIImageJPEGRepresentation(imageView.image, 1);
    
        CIImage *beginImage= [CIImage imageWithData:dataFromImage];
    
        CIContext *context = [CIContext contextWithOptions:nil];
        CIImage *border =[CIImage imageWithData:UIImagePNGRepresentation(borderImage)];
    
        CIFilter *filter= [CIFilter filterWithName:@"CISourceOverCompositing"];  //@"CISoftLightBlendMode"];
        [filter setDefaults];
        [filter setValue:border forKey:@"inputImage"];
    
        [filter setValue:beginImage forKey:@"inputBackgroundImage"];
    
        CIImage *outputImage = [filter valueForKey:@"outputImage"];
        CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
        UIImage *newImg = [UIImage imageWithCGImage:cgimg];
    
        imageView.image = newImg;
    
    }

    Here when any of the border button is clicked this method is fired. at the beginning we preset the image displayed with that of the car.png (that is the image we are changing every time).
    Now we select the borderImage. As the border images are named serially like borderImage1.png, borderImage2.png, this was easier using the tag of the button clicked.
    We take two CIImage, the border image is made of type .png note:

    CIImage *border =[CIImage imageWithData:UIImagePNGRepresentation(borderImage)];

    CISourceOverCompositing type filter is used, which sets any image on top of the background image, but allows the visible portion of background image to be seen. Then we change the CIImage to UIImage and update the imageView.

  • Your application is ready build and run using Ctrl+R
  • You will get the complete code here.
  • The App Produces results like these. (see illustration 3)

[button link=”http://www.youtube.com/watch?v=YDt-TIR_jDA&feature=youtu.be” linking=”new-window” size=”medium” type=”simple” title=”Mosaic Image Gallery with Sencha Touch”]Demo[/button]    [button link=”https://github.com/innofied/photoframing” linking=”new-window” size=”medium” type=”simple” title=”Download” label=”Download”]Download[/button]

bordersAtFinal
illustration 3