How to add cropper on a particular View(other than ImageView) - ios

I need to implement a cropper in my project. Problem is I found croppers that works with UIImageView. But I have a pdf. I am viewing it using code found on vfr/Reader.GitHub. I need to add a cropper, that will crop the particular page of the PDF. In code am using a ScrollView to show the PDF. Any code? any reference that crops the topmost view? Or the Window?

use view.layer.mask property to mask the portion that you want to see.
CAShapeLayer *layer =[CAShapeLayer layer];
layer.path =[UIBezierPath bezierPathWithRect...].CGPath;
view.layer.mask =layer;

If you want a single pdf page, the vfr library already has page thumbnails functionality which are basically single page images.. you can find ways of directly using those thumbnails.
If however you want to 'crop' a portion of the page, you will have to render the PDF page in a core graphics context, allow user to select the area (or select the predefined area as per your requirements) and crop the context.
You can then render this contet wherever you like or convert this context to jpeg data and save it to a file.
Read the iOS Quartz 2D Programming Guide to get a better idea of drawing views, PDFs images etc into core graphics contexts and working with core graphics contexts in more detail:

Related

Storing a graph with Core Plot without displaying it

Is there a way to make Core Plot render a graph even if it is not displayed? I need to do some graphs to share them as images but I can't ask the user to display all plots first so I can save images of them once they are drawn to the screen.
If there is no such possibility: Do you know any other solutions that support simple XY charts with lines and dots.
Core Plot graphs are Core Animation layers. Set the frame to the desired size when you create the graph, set it up normally, and call -imageOfLayer to render it to an NSImage on the Mac or UIImage on iOS. You can also call -dataForPDFRepresentationOfLayer to render it to PDF.

UIGraphicsSetPDFContextURLForRect does not create clickable region on a Core Graphics PDF

I am trying to create a rectangular region on my PDF that will go to a URL. The PDF is created in an iOS app using Core Graphics routines.
In a search to find anyone with a similar problem, I found this Stack Overflow question:
Embed hyperlink in PDF using Core Graphics on iOS
If I use the code provided in the answer of the above question, it sort of works for me. The text shows up and is a clickable link, but if I specify a rectangle that is much larger than the text, only the text is clickable. In addition, modified the code a bit so that I could provide a label and a URL separately, and when I did this and provided an empty string, there was nothing anywhere in the rectangle that was clickable.
However, if I use the UIKit routines for creating a PDF (basically UIGraphicsBeginPDFContextToFile and descendants), then the call to UIGraphicsSetPDFContextURLForRect creates a region in the resulting PDF file that is clickable, even if I do not provide any text.
Here is the method that I am using to create the rectangle link:
+ (void)rectLink:(NSString *)urlString frame:(CGRect)frameRect cropBox:(CGRect)cropBoxRect sourceContext:(CGContextRef)context
{
UIGraphicsPushContext(context);
#ifdef OUTPUT_TEXT_LINK_OUTLINE
CGContextSetLineWidth(context, 5.0);
CGContextSetStrokeColorWithColor(context, [UIColor purpleColor].CGColor);
CGContextStrokeRect(context, frameRect);
#endif
NSURL *url = [NSURL URLWithString:urlString];
UIGraphicsSetPDFContextURLForRect(url, frameRect);
UIGraphicsPopContext();
}
(The OUTPUT_TEXT_LINK_OUTLINE define is something that I am using for testing to make sure that the rectangle I am passing in is in fact where it is supposed to be.)
And here is a call I am making to the above method on the first page of my PDF generation:
[self rectLink:#"http://stackoverflow.com" frame:CGRectMake(474,22,28,28) cropBox:cropBoxRect sourceContext:context];
The variable cropBoxRect refers to the crop box for the current page, and context is the value that I am saving from the CGPDFContextCreateWithURL call at the start of the document.
It is better to write your own writer for writing such annotations to pdf instead of using core graphics APIs, As Apple has not taken PDFKit to cocoa-touch,
- You can follow simplest "incremental update" approach for modifying the pdf which is mentioned in PDF reference 1.7.
- You need to search the page object number in pdf then get /Annots array in it add your annotation token, append its object number to /Annots array
- Make entries for newly added/modified tokens in xref table properly.
- Add trailer token..
This is how you can add any types of annotations into pdf.

How do you get an UIImage from an AVCaptureVideoPreviewLayer?

I have already tried this solution CGImage (or UIImage) from a CALayer
However I do not get anything.
Like the question says, I am trying to get an UIImage from the preview layer of the camera. I know I can either capture a still image or use the outputsamplebuffer but my session quality video is set to photo so either of these 2 aproaches are slow and will give me a big image.
So what I thought could work is to get the image directly from the preview layer, since this has exactly the size I need and the operations have already been made on it. I just dont know how to get this layer to draw into my context so that I can get it as an UIImage.
Perhaps another solution would be to use OpenGL to get this layer directly as a texture?
Any help will be appreciated, thanks.
Quoting Apple from this Technical Q&A:
A: Starting from iOS 7, the UIView class provides a method
-drawViewHierarchyInRect:afterScreenUpdates:, which lets you render a snapshot of the complete view hierarchy as visible onscreen into a
bitmap context. On iOS 6 and earlier, how to capture a view's drawing
contents depends on the underlying drawing technique. This new method
-drawViewHierarchyInRect:afterScreenUpdates: enables you to capture the contents of the receiver view and its subviews to an image
regardless of the drawing techniques (for example UIKit, Quartz,
OpenGL ES, SpriteKit, AV Foundation, etc) in which the views are
rendered
In my experience regarding AVFoundation is not like that, if you use that method on view that host a preview layer you will only obtain the content of the view without the image of the preview layer. Using the -snapshotViewAfterScreenUpdates: will return a UIView that host a special layer. If you try to make an image from that view you won't see nothing.
The only solution I know are AVCaptureVideoDataOutput and AVCaptureStillImageOutput. Each one has its own limit. The first one can't work simultaneously with a AVCaptureMovieFileOutput acquisition, the latter makes the shutter noise.

Duplicate CALayer

I want to create a PDF from a UIView.
Now I want to copy the layer and resize it to a DIN A4 page size.
CGRect A4PageRect = CGRectMake(0, 0, 595, 842);
CALayer *myLayer = [pdfView layer];
myLayer.bounds = pageRect;
But this cody resizes the visible layer on my screen.
How can I copy the layers contents to resize it to fit an A4 page?
Thanks for help, Julian
FWIW, you can make a shallow copy of a CALayer via:
(Swift 3)
let tmp = NSKeyedArchiver.archivedData(withRootObject: myLayer)
let copiedCA = NSKeyedUnarchiver.unarchiveObject(with: tmp) as! CALayer
(or whatever subclass you are using. e.g. CAShapeLayer)
Thanks to: https://stackoverflow.com/a/35345819/1452758
There is no way to duplicate a CALayer.
(It would be difficult for CoreAnimation to implement that in a sensible way. There might be a whole tree of sublayers, and they all might have delegates that influence their behavior, which wouldn't expect to suddenly get requests from the copies of the layers.)
I can only guess at a better solution, because I don't understand your exact situation. Do you have a PDF that you are trying to resize, or do you just want take an arbitrary existing layer and make a PDF document out of it?
If the latter:
Use UIGraphicsBeginPDFContextToData or UIGraphicsBeginPDFContextToFile to create a PDF drawing context
Call UIGraphicsBeginPDFPage or UIGraphicsBeginPDFPageWithInfo to create a page
Call UIGraphicsGetCurrentContext to get the PDF drawing context
Scale using CGContextScaleCTM so your layer will fit in the PDF page
Call -[CALayer renderInContext:] to draw the layer into the PDF context
Call UIGraphicsEndPDFContext to finish the PDF
Note that this may look terrible. Layers are bitmap-based, so you'll get a bitmap in your PDF. Also, -[CALayer renderInContext:] doesn't render exactly the same as it does on-screen -- see the note in the documentation.
If this is a problem, you'll need to add a separate drawing path that bypasses CALayer. In step 5, you would do your own drawing using CoreGraphics.
In your case it's indeed better to go with the proposed solution but for the record, yes you can duplicate - in a way - a CALayer : using CAReplicatorLayer.
It's a very powerful API, not necessary build for duplicating one layer but it works for that too. It works even better for making astonishing visual effects by duplicating series of layers.
For more information you can have a look at the apple official documentation, here an extract:
A layer that creates a specified number of copies of its sublayers (the source layer), each copy potentially having geometric, temporal, and color transformations applied to it.
And here a great tutorial by John Sundell, another extract:
CAReplicatorLayer specializes in drawing multiple copies of an original layer (hence it being a "replicator"), in an efficient - hardware accelerated - manner. It's super useful when drawing things like tiled backgrounds, patterns or other things that should be repeated multiple times. I even use it to implement the texture tiling feature of my upcoming open source Swift game engine.
And finally here a great example of what can be done with this api.

How to Display ngmoco's Fireworks App Over a UIImageView?

Tim Omernick from ngmoco recently gave a talk at Stanford and demonstrated an interesting fireworks app for the iPhone that he posted up the code for here:
gamemakers.ngmoco.com/post/111712416/stanford-university-and-apple-were-kind-enough-to
I can get the app to run when I specify the EAGLView's parent class as a UIView in its header file. However, I want to be able to display the fireworks over an image and so when I tried to specify the parent class as a UIImageView, the background picture I specify seems to hide the firework animation.
Basically, I want to be able to display a UIImage and a EAGLView at the same time. Is this possible? Thanks
I suggest you take the time to learn some OpenGL. It's pretty basic once you understand how it works.
Here's an overview of what you'll need to do.
Create a texture (must be power-of-two size) to hold your image
Upload image pixel data to texture
On each frame:
Bind the texture
Take a quad made out of two triangles and corresponding texture coords and render it
Render the fireworks as before

Resources