Overlay an image (UIImageView) into photo - ios

Is there a way to integrate a UIImageView when taking photos?
I can't seem to find a topic discussing this.
What I wanted to do is to have a UIImageView overlay on the preview. When the shutter is tapped, it should take the picture with the UIImageView embedded in it.
So here's where I am right now. The "test image" part will be made draggable on top of the preview view. I want to include that image with the image I'll be taking when I push the shutter button.
Is this possible? Or is there a better way?
I'm using AVCaptureVideoPreviewLayer, AVCaptureSession and AVCapturePhotoOutput. I'm just putting the UIIMageView above the UIView where the AVCaptureVideoPreviewLayer is also a subview.
EDIT: Tested saving the UIView as an image, and it doesn't include the preview layer (only returns the UIView + UIImageView overlay).

There is at least two ways of doing this.
1) Capture photo from camera and add overlay image based on draggable image view position. This will produce best possible quality.
2) If you don't need photo quality you can use another solution - render draggable view layer in graphic context and video preview layer:
func takePhotoWithOverlay() -> UIImage? {
let overlayImageView // UIImageView with overlay image
let videoPreviewLayer // AVCaptureVideoPreviewLayer
guard let superview = overlayImageView.superview else { return nil }
UIGraphicsBeginImageContextWithOptions(superview.bounds.size, false, 0.0)
defer { UIGraphicsEndImageContext() }
guard let context = UIGraphicsGetCurrentContext() else { return nil }
videoPreviewLayer.render(in: context)
overlayImageView.layer.render(in: context)
return UIGraphicsGetImageFromCurrentImageContext()
}

Related

how to render UIView over UIImageView in swift

I am looking for a way to render UIView over UIImageView on camera in swift. My problem is to capture only small rectangular portion of image.for this i tried by reducing the size of my UIImageView but in this case camera adjusted whole image in this small area which is not my objective.
Finally i decided to hide camera by rendering some other component over it from both side up/down, how can I do?
UIGraphicsBeginImageContextWithOptions(view.bounds.size, true, 0)
view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

How can I add stickers to an image in Swift?

I'm working on a Swift iOS app where I want the user to be able to place an image (a sticker such as a beard or an eyepatch) over another image.
Currently I have it working to where they can take a photo or pull an image up from their Photos and have that display in a UIImage. Obviously next is adding the sticker. I've been able to dig up zero data on this from Google or Stack. And I mean zero.
Does anyone have a general idea of how I would execute this? Specifics would help too of course.
Here's the easy way.
have a UIView as a parent, let's say stickerView
add image to stickerView
add stickers to stickerView
save a snapshot of stickerView
Here's the code to snapshot UIView,
extension UIImage {
class func imageWithView(view: UIView) -> UIImage {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0)
view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img
}
}
Usage
let snapshotImage = UIImage.imageWithView(stickerView)
I would suggest you to add UIImageView for sticker instead of editing image when adding sticker. And after that when save the image then you should edit the image.

Merge two imageViews into one and save iOS swift

I have 2 imageViews like below. (ScrollView has subview of imageView)
i want to take the image of each one and merged to one.
i tried using taking screenshot and crop. but when it comes to different iphone screensizes and resolutions it doesn't work well.
can any one guide me how to do this?
Why not just add them both to one UIView?
It is also possible to add a subview to your image view and extend the frame.
[secondImageView setFrame:CGRectMake(x,y + newImageHeight,width,height)];
[self.myImageView setFrame:CGRectMake(x,y,width,height + newImageHeight)];
[self.myImageView addSubview:secondImageView];
I think your way is right, also you can solve scale size problem very easily with this method.
func mergeScreenshot() {
let layer = UIApplication.sharedApplication().keyWindow.layer
let scale = UIScreen.mainScreen().scale
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale); // reconsider size property for your screenshot
layer.renderInContext(UIGraphicsGetCurrentContext())
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
}
But you should edit sizes again. For example if you're using autolayout you can create IBOutlet and than use it instead of layer.frame.size property which I used.
Hope it helps.

How to add sticker overlay to camera photo

I'm trying to emulate what Celebrity Clicks does: add a celebrity sticker to camera feed, position it and scale it, and than take the photo. This should give you a photo with the sticker applied, which is what Celebrity Click does. However, I'm having trouble merging the camera photo with the sticker. There are a few issues: the sticker scale and position is wrong when applied on the final camera image, because the image taken from the camera is actually much larger both in resolution and in size than the picture shown on the live camera feed when you set up the sticker.
Here is what I'm doing now:
[(GPUImageStillCamera *)videoCamera capturePhotoAsImageProcessedUpToFilter:selectedFilter withCompletionHandler:^(UIImage *processedImage, NSError *error) {
selectedImage = [self imageByCombiningImage:processedImage withImage:celebOverlayView.imageView.image];
}];
- (UIImage*)imageByCombiningImage:(UIImage*)firstImage withImage:(UIImage*)secondImage {
UIImage *image = nil;
CGSize newImageSize = CGSizeMake(MAX(firstImage.size.width, secondImage.size.width), MAX(firstImage.size.height, secondImage.size.height));
if (UIGraphicsBeginImageContextWithOptions != NULL) {
UIGraphicsBeginImageContextWithOptions(newImageSize, NO, [[UIScreen mainScreen] scale]);
} else {
UIGraphicsBeginImageContext(newImageSize);
}
[firstImage drawInRect:cameraView.frame];
[firstImage drawAtPoint:CGPointMake(roundf((newImageSize.width-firstImage.size.width)/2),
roundf((newImageSize.height-firstImage.size.height)/2))];
[secondImage drawAtPoint:CGPointMake(roundf((newImageSize.width-secondImage.size.width)/2),
roundf((newImageSize.height-secondImage.size.height)/2))];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
I have attached the before and after photo, so that you can see my problem.
Camera setup screen:
Photo taken with camera with the sticker applied:
I'm guessing that there is a better way to merge the two images or to simply apply the sticker at given coordinates to the camera captured image. Any suggestions?
It is easiest if you save the relative frame of the added view in the picker and then compute the new frame when applying the added image combining the two images.
One of the many ways to do so is to divide all the parameters of the frame with the superview width and height respectively when taking the photo and then multiplying the same frame coordinates with the image width and height when trying to merge the two images.
Also for what you are doing I suggest you lose the core graphics to draw the image content and rather just use the image view: Crate the image view with the size of the background image, set the image then add another image view with the added image and set the frame as described above. Then simply create a screenshot of the view and your image is done. This way you will have no issues with scaling, transforms and such.

Draw the zoomed & panned portion of a UIScrollview as a new UIImage

I would like to draw a thumbnail of a UIScrollview.
This scrollview has an image in. However the user can zoom and pan the image.
When the user has panned and zoomed to where he wants the picture, I want to create a thumbnail of what they set up. Basically, I want to create a brand new uiimage that is sized at say 100x100, but uses the exact image data that the scrollview is currently showing.
I tried this, but the more I zoom in, the more distorted the images became.
//returns a smaller UIImage
func generateThumbnailOfSize(size:CGSize)->UIImage
{
UIGraphicsBeginImageContext(_scrollView.bounds.size)
_scrollView.layer.renderInContext(UIGraphicsGetCurrentContext())
var fullsizeCroppedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width, size.height), fullsizeCroppedImage.CGImage)
var sizeAdjustedCroppedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()//gets the image as it looks in the scrollview
UIGraphicsEndImageContext()
return sizeAdjustedCroppedImage
}
Suggestions?:)
Swift & Objc code welcome!
You may want to have a look at this:
Crop UIImage in UIScrollView like in "Move And Scale"
In case anyone is interested in more sophisticated solution:
https://github.com/barrettj/BJImageCropper

Resources