Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize UIImage's canvas and fill the empty place with color?

In simple words I want to "revert" the crop operation. In crop you choose a rect and cut the image to the specified rect. In my case I need to do the opposite thing - to add empty space around the image and fill it with color. Note - image may have transparent background so I can't just draw one image over another image.

All the input data (rects and image) I already have. How to solve this task?

like image 567
Vyachaslav Gerchicov Avatar asked Nov 27 '17 08:11

Vyachaslav Gerchicov


People also ask

How do you fill canvas in gimp?

Use Layer>Layer to image size to enlarge the layer so that it fills the canvas. (*) Use Image>Fit canvas to layers to shrink the canvas around the layer so the fill isn't needed.


1 Answers

Basic process:

  1. Create a solid-color UIImage
  2. Get a CGContext
  3. Clear a rect in the center of the new UIImage with (Obj-C) CGContextClearRect(CGContextRef c, CGRect rect); or (Swift) .clear(_ rect: CGRect)
  4. Draw the original image into the "transparent rect" of the new image

Here is an example, using Swift:

func drawImageOnCanvas(_ useImage: UIImage, canvasSize: CGSize, canvasColor: UIColor ) -> UIImage {

    let rect = CGRect(origin: .zero, size: canvasSize)
    UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)

    // fill the entire image
    canvasColor.setFill()
    UIRectFill(rect)

    // calculate a Rect the size of the image to draw, centered in the canvas rect
    let centeredImageRect = CGRect(x: (canvasSize.width - useImage.size.width) / 2,
                                   y: (canvasSize.height - useImage.size.height) / 2,
                                   width: useImage.size.width,
                                   height: useImage.size.height)

    // get a drawing context
    let context = UIGraphicsGetCurrentContext();

    // "cut" a transparent rectanlge in the middle of the "canvas" image
    context?.clear(centeredImageRect)

    // draw the image into that rect
    useImage.draw(in: centeredImageRect)

    // get the new "image in the center of a canvas image"
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image!

}

and call it like this:

    if let img = UIImage(named: "myimage") {

        let expandedSize = CGSize(width: img.size.width + 60, height: img.size.height + 60)

        let imageOnBlueCanvas = drawImageOnCanvas(img, canvasSize: expandedSize, canvasColor: .blue)

        let v = UIImageView(image: imageOnBlueCanvas)

        view.addSubview(v)

    }
like image 191
DonMag Avatar answered Sep 29 '22 07:09

DonMag