Taking SnapShot in MPMovieController in iOS - ios

I am working on a project where I take the HTTP streaming video and display it in the MPMoviePlayerController. And I have to take the snapshot of that streaming video.
I used following code to do that, but I get only nil value.
UIImage *thumbnail = [mpPlayer thumbnailImageAtTime:yourMoviePlayerObject.currentPlaybackTime
timeOption:MPMovieTimeOptionNearestKeyFrame];

You can use UIGraphics to take screenshot:
CGSize imageSize = set_image_size_here;
UIGraphicsBeginImageContext(imageSize);
CGContextRef imageContext = UIGraphicsGetCurrentContext();
[mpPlayer.view.layer renderInContext:imageContext];
Retrieve screenshot image
UIImage *imagefinal = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Related

Am I losing resolution after grabbing image of screen then cropping it?

I have some code where I'm grabbing an image of the screen, and then cropping it based on some boundary values:
UIGraphicsBeginImageContextWithOptions(self.mainView.bounds.size, NO, 0.0);
[self.mainView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *comicImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContextWithOptions(CGSizeMake(boundary.width, boundary.height), NO, 0.0);
[comicImage drawAtPoint:CGPointMake(-boundary.xMin, -boundary.yMin)];
comicImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
What I'm wondering is, am I producing a poor quality image with low resolution using the above method? Is there a better way to go about doing this?
Maybe,you can use the follow code
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);

how to take a screenshot with bitmap on iOS

I have a feature, I want to take a screenshot of a UIView(called "arrangeView" in my codes). and send the picture to my server, and then I will print it, so I want a high quantity picture..
My codes:
UIGraphicsBeginImageContext(arrangeView.frame.size);
[arrangeView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//save and send method
[self saveImage:newImage WithName:imgTitle];
With these codes I have 2 issues:
the picture quality is too low. because after I uploaded to the
server, I will print it. but the picture I got with the codes only
20~40k, it is too small to print.
one friend told me that the app store don't alow app take a screenshot and send it to the server. he told me to use bitmap.
And I searched in google, I don't find a good solution for it. Would someone help?
Thank you very much.
Screen shot you get will be of same resolution as you main screen size i.e If it is iPhone 5s it will be 640 x 1136. Best way to get screen shot is:
UIView *screenShotView = [arrangeView snapshotViewAfterScreenUpdates:YES];
Please try to use the code below.you may save first in photo album and then you can send to server
UIView* captureView = self.view;
/* Capture the screen shoot at native resolution */
UIGraphicsBeginImageContextWithOptions(captureView.bounds.size, captureView.opaque, 0.0);
[captureView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
/* Render the screen shot at custom resolution */
CGRect cropRect = CGRectMake(0 ,0 ,1435 ,1435);
UIGraphicsBeginImageContextWithOptions(cropRect.size, captureView.opaque, 1.0f);
[screenshot drawInRect:cropRect];
UIImage * customScreenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
/* Save to the photo album */
UIImageWriteToSavedPhotosAlbum(customScreenShot , nil, nil, nil);

Video stream in AVSampleBufferDisplayLayer doesn't show up in screenshot

I've been using the new Video Toolbox methods to take an H.264 video stream and display it in a view controller using AVSampleBufferDisplayLayer. This all works as intended and the stream looks great. However, when I try to take a screenshot of the entire view, the contents of the AVSampleBufferDisplayLayer (i.e. the decompressed video stream) do not show up in the snapshot. The snapshot shows all other UI buttons/labels/etc. but the screenshot only shows the background color of the AVSampleBufferDisplayLayer (which I had set to bright blue) and not the live video feed.
In the method below (inspired by this post) I take the SampleBuffer from my stream and queue it to be displayed on the AVSampleBufferDisplayLayer. Then I call my method imageFromLayer: to get the snapshot as a UIImage. (I then either display that UIImage in the UIImageView imageDisplay, or I save it to the device's local camera roll to verify what the UIImage looks like. Both methods yield the same result.)
-(void) h264VideoFrame:(CMSampleBufferRef)sample
{
[self.AVSampleDisplayLayer enqueueSampleBuffer:sample];
dispatch_sync(dispatch_get_main_queue(), ^(void) {
UIImage* snapshot = [self imageFromLayer:self.AVSampleDisplayLayer];
[self.imageDisplay setImage:snapshot];
});
}
Here I simply take the contents of the AVSampleBufferDisplayLayer and attempt to convert it to a UIImage. If I pass the entire screen into this method as the layer, all other UI elements like labels/buttons/images will show up except for the AVDisplayLayer. If I pass in just the AVDisplayLayer, I get a solid blue image (since the background color is blue).
- (UIImage *)imageFromLayer:(CALayer *)layer
{
UIGraphicsBeginImageContextWithOptions([layer frame].size, YES, 1.0);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
//UIImageWriteToSavedPhotosAlbum(outputImage, self, nil, nil);
UIGraphicsEndImageContext();
return outputImage;
}
I've tried using UIImage snapshot = [self imageFromLayer: self.AVSampleDisplayLayer.presentationLayer]; and .modelLayer, but that didn't help. I've tried queueing the samplebuffer and waiting before taking a snapshot, I've tried messing with the opacity and xPosition of the AVDisplayLayer... I've even tried setting different values for the CMTimebase of the AVDisplayLayer. Any hints are appreciated!
Also according to this post, and this post other people are having similar troubles with snapshots in iOS 8.
I fixed this by switching from AVSampleDisplayLayer to VTDecompressionSession. In the VTDecompression didDecompress callback method, I send the decompressed image (CVImageBufferRef) into the following method to get a screenshot of the video stream and turn it into a UIImage.
-(void) screenshotOfVideoStream:(CVImageBufferRef)imageBuffer
{
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer];
CIContext *temporaryContext = [CIContext contextWithOptions:nil];
CGImageRef videoImage = [temporaryContext
createCGImage:ciImage
fromRect:CGRectMake(0, 0,
CVPixelBufferGetWidth(imageBuffer),
CVPixelBufferGetHeight(imageBuffer))];
UIImage *image = [[UIImage alloc] initWithCGImage:videoImage];
[self doSomethingWithOurUIImage:image];
CGImageRelease(videoImage);
}

Crop Image using CGRect

I have been trying to do this since forever. I have a camera overlay. I want to get my final image to be the part of the image viewable from the in-built camera.
What I did was make CGRect with dimensions equal to the square in the camera. Then I tried cropping it using this function.
- (UIImage *)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return croppedImage;
}
I called it like this
CGRect rect = CGRectMake(10, 72, 300, 300);
UIImage *realImage = [self imageByCropping:[self.capturedImages objectAtIndex:0] toRect:rect];
What I get is a bad quality image with the wrong orientation.
::EDIT::
With Nitin's answer I can crop the correct part of the screen but the problem is it crops the view that follows the camera view, 'the confirmation view'. I suspect this is because Nitin's code uses
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
and because the ViewController in which all this is happening because the View Controller for the Confirmation View is the Controller in which this code is being executed. I will try to explain this with a small map
CameraOverlay.xib(it uses this xib to create an overlay) <===== CameraOverlayViewController ---------> ConfirmationView
So when first the ViewController is evoked(button on Tab bar), it opens the camera(UIImagePickerController) with an overlay over it. Then once user clicks an image, the image is shown on the ConfirmationView.
What I think is happening is when
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, YES, 1.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
these lines are being executed, the View at that time is ConfirmationView.
Note: I call the function in
(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info method.
Refer Drawing and printing Guide.
The default coordinate system is different between CoreGraphics and UIKit. I think your issue is because of this fact.
Using these may help you solve the issue
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context , 0.0, rect.size.height);
CGContextScaleCTM(context , 1.0, -1.0);

Ios taking snapshot of a screen after cropping some parts

Yep as the title says I need to take a cropped snapshot of my app.
I want to cut top of the screenshot little bit (%20) I already have a code which I used to take a snapshot and send it to facebook and its working but its taking the photo of all of the screen so how can tell my code to ignore the %20 percent of the screen.Maybe with height and width also I looked some questions in the stack overflow and manage to slide my screenshot so I get rid of the unwanted part at the top but this time at the bottom huge white area appeared so it didnt solve my problem.
Here is my snapshot code
UIGraphicsBeginImageContext(self.ekran.bounds.size);
[self.ekran.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
A method to crop the image, that accepts any frame to crop the image against
- (UIImage *)cropImage:(UIImage *)imageToCrop toRect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return cropped;
}
Use it as follows:
UIGraphicsBeginImageContext(self.ekran.bounds.size);
[self.ekran.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGFloat imgHight = resultingImage.size.height;
// Create a frame that crops the top 20% of the image
CGRect* imageFrame = CGRectMake(0, imgHight - (imgHight*0.8), width, imgHight*0.8);
resultingImage = [self cropImage:resultingImage toRect:imageFrame];

Resources