Generate an Image from a Map in iOS - ios

Here's what I want to do:
Get some destination.
Render it in the maps into a view.
Turn that into an image I can then save and use as a background.
Another option would be to put a map view down, turn off all input and just paint on top of it. Basically asking for a way to rasterize the map view. Wondering if anyone has done this.

You can render any view into an image with something like this:
UIGraphicsBeginImageContextWithOptions(mapView.bounds.size, NO, 0.0f);
[mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *mapImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Related

iOS, how to add a blur effect to a background view?

I'm trying to add a blur effect to a background view.
Here's my background view.
https://github.com/martinjuhasz/MJPopupViewController/blob/master/Source/MJPopupBackgroundView.m
I believe that the idea is to take a snapshot of the parent view and then add a blur effect to that image.
I've seen various approaches not sure what will work and what is the best approach.
Also I'm not sure where I'd create the snapshot.
The most common way is indeed probably just to take a snapshot and blur that.
You can take a snapshot by doing something like this:
+ (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0f);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
UIImage * snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshotImage;
}
Keep in mind this is a fast iOS7+ blurring method so if you want to support lower versions of iOS you will need to use a slower method, detailed in this answer.
There are a lot of ways to achieve blur, the 2 most popular are probably to use Apple's UIImageEffects WWDC sample code which can be found here, or to use GPUImage, which can be found here.
Ablow link points to present view and affect the background with blur effect
https://stackoverflow.com/a/52374977/5233180

Printing shinobi chart into PDF

I have several shinobicharts in my App that I want to print into a PDF file. Everything else, like normal views, labels and images work fine, even the grid, legend and gridlabels are displayed. The only thing missing are the series. So basically I get an empty chart printed into the PDF file.
I print the PDF as follows:
NSMutableData * pdfData=[NSMutableData data];
PDFPage1ViewController *pdf1 = [self.storyboard instantiateViewControllerWithIdentifier:#"PDF1"];
pdf1.array1 = array1;
pdf1.array2 = array2;
pdf1.array3 = array3;
pdf1.array4 = array4;
UIGraphicsBeginPDFContextToData(pdfData, CGRectZero,nil);
CGContextRef pdfContext=UIGraphicsGetCurrentContext();
UIGraphicsBeginPDFPage();
[pdf1.view.layer renderInContext:pdfContext];
UIGraphicsEndPDFContext();
The exact same code from PDF1PageViewController draws beautiful charts in a normal viewController, not missing the series.
The arrays contain the data which should be displayed.
[EDIT]
This code did it for me:
UIGraphicsBeginImageContextWithOptions(pdf1.view.bounds.size, NO, 0.0);
[pdf1.view drawViewHierarchyInRect:pdf1.view.bounds afterScreenUpdates:YES];
UIImage *pdf1Image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *pdf1ImageView = [[UIImageView alloc] initWithImage:pdf1Image];
[pdf1ImageView.layer renderInContext:pdfContext];
Although the activity wheel stops spinning after drawViewHierarchyInRect and the label displaying the current page being rendered also stops updating. Anyone knows how to fix this?
The reason that you're having this problem is that the series part of the charts are rendered in openGLES, and therefore don't get rendered as part of renderInContext:.
You have a couple of options which you can investigate using. the first is the addition of some snapshotting methods on UIView in iOS7. If you're app can be restricted to iOS7 only, then snapshotViewAfterScreenUpdates: will return you a UIView which is a snapshot of the content. I think that the following (untested) code will work:
UIGraphicsBeginPDFPage();
UIView *pdfPage = [pd1.view snapshotViewAfterScreenUpdates:YES];
[pdfPage.layer renderInContext:pdfContext];
UIGraphicsEndPDFContext();
There are more details on this approach on the ShinobiControls blog at http://www.shinobicontrols.com/blog/posts/2014/02/24/taking-a-chart-snapshot-in-ios7
If restricting your app to iOS7 isn't an option then you can still achieve the result you want, but it is a little more complicated. Luckily, again, there is a blog post on the ShinobiControls blog (http://www.shinobicontrols.com/blog/posts/2012/03/26/taking-a-shinobichart-screenshot-from-your-app) which describes how to create a UIImage from a chart. This could easily be adapted to render into your PDF context, rather than the image context created in the post. There is an additional code snippet to accompany the post, available on github: https://github.com/ShinobiControls/charts-snippets/tree/master/iOS/objective-c/screenshot.
Hope this helps
sam

Fill color on specific portion of image?

I want to fill specific color on specific area of an image.
EX:
In above Joker image, If touch on hair of Joker then fill specific color on hair Or touch on nose then fill specific color on nose.. etc. I hope may you understand what I am trying to say.
After googling it's may be achieve by use of UIBezierPath or CGContext Reference but I am very new for it, I tried to read this documentation but I do not understand (take more time) anything also I have limit of time for this Project. So I can not spend more time on it.
Also I found that we can use Flood fill algorithm. But I don't know how to use in my case.
NOTE: I don't want to divide original image (such like hair. nose, cap,...etc) because If I will do then there will be so many images in bundle so I need to handle it for both normal and retina device so this option is not helpful for me.
So please give me your valuable suggestion and also tell me which is best for me UIBezierPath or CGContext Reference? How can I fill color on specific portion of image? and/or can we fill color under the black border of area ? Because I am new at Quartz 2D Programming.
Use the Github library below. The post uses the flood fill algorithm : UIImageScanlineFloodfill
Objective C description : ObjFloodFill
If you want to look at detailed explanation of the algorithm : Recursion Explained with the Flood Fill Algorithm (and Zombies and Cats)
few of the other tutorials in other languages : Lode's Computer Graphics Tutorial : Flood Fill
Rather than attempting to flood fill an area of a raster-based image, a better approach (and much smaller amount of data) would be to create vector images. Once you have a vector image, you can stroke the outline to draw it uncolored, or you can fill the outline to draw it colored.
I recommend using CoreGraphics calls like CGContextStrokePath() and CGContextFillPath() to do the drawing. This will likely look better than using the flood fill because you will get nicely anti-aliased edges.
Apple has some good documentation on how to draw with Quartz 2D. Particularly the section on Paths is useful to what you're trying to do.
You can Clip the context based on image Alpha transparency
I have created a quick image with black color and alpha
Then using the below Code
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext(); // Get the context
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor); // Set the fill color to be blue
// Flip the context so that the image is not flipped
CGContextTranslateCTM(context, 0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Clip the context by a mask created from the image
UIImage *image = [UIImage imageNamed:#"image.png"];
CGImageRef cgImage = image.CGImage;
CGContextClipToMask(context, rect, cgImage);
// Finally fill the context with the color and mask you set earlier
CGContextFillRect(context, rect);
}
The result
This is a quick hint of what you can do. However you need now to convert your image to add alpha transparent to the parts you need to remove
After a quick search I found these links
How can I change the color 'white' from a UIImage to transparent
How to make one colour transparent in UIImage
If You create your image as SVG vector base image, it will be very light (less than png, jpg) and really easy to manage via Quartz 2D using bezier paths. Bezier paths can be filled (white at starting). UIBezierPath have a method (containsPoint:) that help define if you click inside.

Capturing CATiledLayer content to another layer or image context

I'm trying to screen capture a view that uses CATiledLayers (for animation) but unable to get the image that I want.
I tried it on Apple's "PhotoScroller" sample application and added this:
UIGraphicsBeginImageContext(self.view.frame.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.view.layer renderInContext:ctx];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
However, the tiles don't render in the resulting UIImage and all I get is the tile outlines.
Seems that CATiledLayer's renderInContext behaves differently from CALayer.
Am I doing anything wrong in trying to capture the tiles? Is my only solution to render the tiles individually myself?
In the end, rather than trying to render the tiles into another view just for animation, I just created a new instance of ImageScrollView, and animated the original one and the new one together before deallocating the original one.

iOS -> saving 2 UIImageView to cameraRoll

i have two layers of UIImageView, upper one is partly transparent, second in is 'background'. I want to save them both like user see them from front into cameraRoll for user's use. The problem is writing it in way:
if(gridUpperLayer == transparent) {drawGridLowerLayer}
else {drawGridUpperLayer}
will be very slow (and i dont know how to implement it). Anybody has idea how to do it in faster way..? Best would be with example but i would be grateful for anything ^^
Cheers and thank you in advance!
You can do this by rendering the CALayer into an image for the UIView that contains both of the images. The following code would look like:
UIGraphicsBeginImageContext(containerView.frame.size);
[containerView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *anImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//save anImage to disk

Resources