UIImage manipulation IOS - ios

In Order to create a matrix and manipulate the pixels of the image, should i convert the image to bitmap?
My application is about taking a picture from camera or library and when i touch a part of the image , this region of the image should stretch.
Here is the code that i tired to convert the UIImage to bitmap:
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(-20, -20, -20, -20);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
imageView.image = [[UIImage imageNamed:#"number1.png"] resizableImageWithCapInsets:edgeInsets];
[self.view addSubview:imageView];
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 0.0);
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *bmImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSArray *documentsPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentsPaths objectAtIndex:0];
[UIImagePNGRepresentation(bmImage) writeToFile:[documentsDir stringByAppendingString:#"num1.png"] atomically:YES];
Thanks for your help

The right approach to your problem is tessellating the image and then distorting the tessellation grid. This is a common technique in computer graphics (e.g. with OpenGL).
You can either try that yourself or use an existing specialised framework like GPUImage. It offers a lot of filters and distortion effects pre-made. Just go to the linked page and search the page for "distortion". You have pinch distortion, swirl distortion, bulge distortion, and so on.
You will possibly need to get one of those classes and modify it a bit so that the effect is applied around a moving center, but that should not be that difficult.
BTW: what you are doing in your code in not really useful, since you already have a UIImage, so you do not need to put it in a UIImageView and render the view into a bitmap context to come out with another UIImage.

Related

How to create shadow effect on UIImage bounds

I have a UIImageView in which I have a UIImage obviously. I want to create a shadow effect only on the UIImage. My problem is that I cannot get the CGRect of the UIImage inside the UIImageView so I can apply the shadow effect on it by using the following method.
[mImageView.layer.shadowColor = [UIColor grayColor].CGColor;
mImageView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
mImageView.layer.shadowOpacity = 0.9f;
mImageView.layer.masksToBounds = NO;
CGRect imageFrame = mImageView.frame;
UIEdgeInsets shadowInsets = UIEdgeInsetsMake(0, 0, -1.5f, 0);
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:UIEdgeInsetsInsetRect(imageFrame, shadowInsets)];
mImageView.layer.shadowPath = shadowPath.CGPath;
Please consider the image attached for this problem.
The problem is critical too because the UIImage can be an image of a rigid dimension because it is a cropped image as you can see in the picture attached.
The UIImageView’s bound is equal to the view’s bound here. So when applying the effect using the method above, it creates a UIBezierPath on the whole UIImageView, not only to the UIImage. As in the method, I cannot get the exact CGRect of the UIImage.
Any solution? What am I missing?
cropped image
UIImage is always rectangular, so is UIImageView. I believe you want to put shadow only around the jagged border of the cropped area right? If that is the case, you cannot use this method. You need to use CoreGraphics or others, to get the effect you want. For example, you can create a copy of this image in memory, blackened it, and blur it and paste it behind your image to create a shadowy effect.

Xcode: Image becomes filled with color on UIBarItem while scaling, function initeWithImage(UIImage)

please, help me to find some solution to the following problem. IOS, Xcode.
I have UIBarItem component - the button that switches languages on the toolbar. The bar has function initeWithImage(UIImage). The problem is when i am trying to scale the image it becomes filled with color...The picture is too big for the toolbar. I have changed the size of the picture manually, but it looks ugly (i need scaling).
I have tried to solve the problem:
1. trough Scale
2. through Frame size
3. and variations of the two above :)
Some code:
self initWithImage:image //
style: UIBarButtonItemStyleBordered //UIBarButtonItemStylePlain
target:target
action:action
UIImage *image;
image = [[UIImage imageNamed:#“image.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
-(UIImage )imageWithImages:(UIImage )image scaledToSize:(CGSize)newSize {
//UIGraphicsBeginImageContext(newSize);
// In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
// Pass 1.0 to force exact pixel size.
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Please, help me with this. Quite simple but tricky task. I have already spent several hours with that... Thank you in advance :)
You should not use initWithImage method.
If you want to display the exact image you should use initWithCustomView method.
For example:
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image"]];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:imageView];
You can scale down the image before setting it to the image view if you want to.

UIImage Distortion from UIGraphicsBeginImageContext with larger files (pixel formats, codecs?)

I'm cropping UIImages with a UIBezierPath using UIGraphicsContext:
CGSize thumbnailSize = CGSizeMake(54.0f, 45.0f); // dimensions of UIBezierPath
UIGraphicsBeginImageContextWithOptions(thumbnailSize, NO, 0);
[path addClip];
[originalImage drawInRect:CGRectMake(0, originalImage.size.height/-3, thumbnailSize.width, originalImage.size.height)];
UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
But for some reason my images are getting stretched vertically (everything looks slightly long and skinny), and this effect is stronger the bigger my originalImage is. I'm sure the originalImages are perfectly fine before I do these operations (I've checked)
My images are all 9:16 (say 72px wide by 128px tall) if that matters.
I've seen UIGraphics creates a bitmap with an "ARGB 32-bit integer pixel format using host-byte order"; and I'll admit a bit of ignorance when it comes to pixel formats, but felt this MAY be relevant because I'm not sure if that's the same pixel format I use to encode the picture data.
No idea how relevant this is but here is the FULL processing pipeline:
I'm capturing using AVFoundation and I set my photoSettings as
NSDictionary *photoSettings = #{AVVideoCodecKey : AVVideoCodecH264};
capturing using captureStillImageAsynchronouslyFromConnection:.. then turning it into NSData using [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; then downsizing into thumbnail by creating a CGDataProviderRefWithCFData and converting to CGImageRef using CGImageSourceCreateThumbnailAtIndex and getting a UIImage from that.
Later, I once again turn it into NSData using UIImageJPEGRepresentation(thumbnail, 0.7) so I can store. And finally when I'm ready to display I call my own method detailed on top [self maskImage:[UIImage imageWithData:imageData] toPath:_thumbnailPath] and display it on a UIImageView and set contentMode = UIViewContentModeScaleAspectFit.
If the method I'm using to mask the UIImage with the UIBezierPath is fine, I may end up explicitly setting the photoOutput settings with [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey, nil] and the I can probably use something like how to convert a CVImageBufferRef to UIImage and change a lot of my code... but I really rather not do that unless completely necessary since, as I've mentioned, I really don't know much about video encoding / all these graphical, low level objects.
This line:
[originalImage drawInRect:CGRectMake(0, originalImage.size.height/-3, thumbnailSize.width, originalImage.size.height)];
is a problem. You are drawing originalImage but you specify the width of thumbnailSize.width and the height of originalImage. This messes up the image's aspect ratio.
You need a width and a height based on the same image size. Pick one as needed to maintain the proper aspect ratio.

How to apply custom zoom to UIImagePicker camera?

I have an custom camera control having slider to apply zoom. I am able to zoom image with following code:
self.pickerReference.cameraViewTransform = CGAffineTransformScale(CGAffineTransformIdentity, zoom, zoom);
But when i get image in didFinishPickingMediaWithInfo I get original image for UIImagePickerControllerOriginalImage, not the zoomed one. And for UIImagePickerControllerEditedImage there is no image.
I have also tried:
currentImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
UIImageView *v = [[UIImageView alloc]initWithImage:currentImage];
UIGraphicsBeginImageContext(v.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextScaleCTM(context, zoom, zoom);
[v drawRect:pickerReference.view.bounds];
CGContextRestoreGState(context);
zoomedCurImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Write image to PNG file
[UIImageJPEGRepresentation(zoomedCurImg, 0.4) writeToFile:imgPath atomically:YES];
This does apply zoom to original image but zoom is applied always at top left corner & not to where it is to be applied.
Please suggest solution. Thanks in advance.
I had a similar issue with a different piece of code and turning off auto layout fixed it for me. Not sure if that applies here but it's worth a shot.

iOS light linen background?

I really want to know if there's a way to get iOS's light linen background. Here's what it looks like:
Is there a way to access this by merely using the built-in SDK? Or do I have to find an image like this somewhere?
EDIT: I didn't want to use private APIs, so here's what I did. I grabbed the image this way:
CGRect rect = CGRectMake(0.0f, 0.0f, 640.0f, 960.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [[UIColor underPageBackgroundColor] CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imagepath = [documentsDirectory stringByAppendingPathComponent:#"underPageBackground.png"];
[UIImagePNGRepresentation(image) writeToFile:imagepath atomically:YES];
And here is the resulting png in retina resolution: (click on thumbnail to open)
Hope this is useful to someone. :)
Use [UIColor underPageBackgroundColor]. And here is a link with useful information and samples.
I'm not sure it is exactly the one (seems darker to me) but, you can choose the "Scroll View Textured Background Color" in Interface Builder. To do so, when selection a color choose the dropbox to the right instead of the color box on the left.
I believe you should be able to find this background in the SDK(it should be the default one for this kind of "flick page up" function) or on google (try looking for UIStockImageUnderPageBackground.png).
Otherwise - it looks like a pattern. What you could do is to import the attached screenshot, then cut a bit without the shadows and fill a blank canvas with it, so that the sides match forming the original pattern.
This isn't really a solution to get the actual image but you can easily just make the texture. I just pulled up a tutorial on how to make it in photoshop. iOS Linen tute here
This way you can make it whatever color you want!

Resources