I am able to save the contents of a UIView as an image to the library.
The image i am trying to save is very a good resolution on the app, but saving it to the photo library reduces the resolution significantly. The image i am trying to save, is of the same width as the screen but many times the height of the screen.
The image i save looks like how i want on the UIScrollView in the app but the image it saves has a lower resolution than the actual image. How can i prevent it from doing this?
Thanks in advanced :D
edit: adding the code...
- (void) saveImageToLibrary
{
UIImage* image;// = nil;
UIGraphicsBeginImageContext(scrollview.contentSize);
{
CGPoint savedContentOffset = scrollview.contentOffset;
CGRect savedFrame = scrollview.frame;
scrollview.contentOffset = CGPointZero;
scrollview.frame = CGRectMake(0, 0, scrollview.contentSize.width, scrollview.contentSize.height);
self.view.frame = CGRectMake(0, 0, scrollview.contentSize.width, scrollview.contentSize.height);
[scrollview.layer renderInContext: UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();
scrollview.contentOffset = savedContentOffset;
scrollview.frame = savedFrame;
self.view.frame = savedFrame;
}
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(image, nil,nil,nil);
}
i hope this is helpful.
Are you setting the correct scale when you try to create the image? Could you post the code?
OK guys and goyals... i think i figured out the problem.
the issue is the iPhone simulator. depending on the hardware you are sumulating, image will be optimised for the resolution of the sumilator.
im not entirely conviced by this because i was previously simulating an iPhone 5 (which has retina display), but simulating iphone 6 seems to work fine.
here is a link if you want to follow further details or if you want to add to this thread :D
https://stackoverflow.com/questions/8032528/uiimage-image-loaded-from-appbundle-is-saved-at-lower-resolution-in-app-direct
Use this instead:
UIGraphicsBeginImageContextWithOptions(scrollView.contentSize, scrollView.opaque, [[UIScreen mainScreen] scale]);
EDIT
You can also try setting the scale to zero:
UIGraphicsBeginImageContextWithOptions(scrollView.contentSize, scrollView.opaque, 0.0);
Does that help you?
Related
I am using custom png images for items of .tabBarItem of my UITabBarController.
But my png images are too big (64x64), so I use the method below to redraw the image in a smaller rect (for example, make the size parameter (25,25) ).
-(UIImage*) getSmallImage:(UIImage*)image inSize: (CGSize)size
{
CGSize originalImageSize = image.size;
CGRect newRect = CGRectMake(0, 0, size.width, size.height);
float ratio = MAX(newRect.size.width/originalImageSize.width,
newRect.size.height/originalImageSize.height);
UIGraphicsBeginImageContextWithOptions(newRect.size, NO, 0.0);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:newRect cornerRadius:5.0];
[path addClip];
CGRect projectRect;
projectRect.size.width = ratio * originalImageSize.width;
projectRect.size.height = ratio * originalImageSize.height;
//projectRect.origin.x = (newRect.size.width - projectRect.size.width) / 2.0;
//projectRect.origin.y = (newRect.size.height - projectRect.size.height) / 2.0;
// Draw the image on it
[image drawInRect:projectRect];
// Get the image from the image context
UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
// Cleanup image context resources
UIGraphicsEndImageContext();
return smallImage;
}
Every image I use was returned by this method. Everything was fine on simulators, but those images were not displaying when I test them on my iphone.
But if I abandon the method above and import the image directly like this: self.tabBarItem.image = [UIImage imageNamed:#"Input"]; Then the images were correctly shown on my phone, but only too big.
How can I fix this problem?
I'll answer this question by myself.
After hours of debugging, here is the problem:
in the method given above, originproperty of CGRect projectRectwas not set.
After I set both origin.x & origin.y to 0, everything worked out.
Tip: every time you meet a WTF problem, be patient and try to test your code in different ways. 'Cause in 99.9% of this kind of cases, there is something wrong with your code in stead of a bug of Xcode.
Though I still don't know why the code in my question works well in simulators, I'll let it go because I guess someday when I become an expert, this kind of question would be easy as well as silly.
I'm trying to get an image of the contents of a UITextView, including the part that is not currently visible on the screen. I do it exactly as pointed out in the first answer here:
Getting a screenshot of a UIScrollView, including offscreen parts, except for using a UITextView instead of a UIScrollView. Unfortunately, no matter what changes I do to the code, I'm always only getting a part of my UITextView, which is about 1024x315 (I test it on the iPad simulator, in landscape orientation). Why is the size so weird and how can I make it as I want to?
That's how I'm saving the image (ResultsView is an instance of UITextView):
UIImage* image = nil;
UIGraphicsBeginImageContext(ResultsView.contentSize);
CGPoint savedContentOffset = ResultsView.contentOffset;
CGRect savedFrame = ResultsView.frame;
ResultsView.contentOffset = CGPointZero;
ResultsView.frame = CGRectMake(0, 0, ResultsView.contentSize.width, ResultsView.contentSize.height);
[ResultsView.layer renderInContext: UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();
ResultsView.contentOffset = savedContentOffset;
ResultsView.frame = savedFrame;
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(image);
UIImageWriteToSavedPhotosAlbum([UIImage imageWithData:data], nil, nil, nil);
I have an image (png) which must fill the entire screen of my app. I'm using CALayers and doing everything programatically but still this sounds like something that should be trivial to but I can't get it to work. I have two versions of the image a retina version (2048px x 1536px) and a non-retina version 1024px x 768px). The image is listed a universal image in the Asset catalogue
The code is simple enough I think:
// CREATE FULL SCREEN CALAYER
CALayer *myLayer = [[CALayer alloc] init];
[myLayer setBounds:CGRectMake(0, 0, bounds.size.width, bounds.size.height)];
[myLayer setPosition:CGPointMake(bounds.size.width/2, bounds.size.height/2)];
[self.view.layer addSublayer:myLayer];
// LOAD THE IMAGE INTO THE LAYER —— AM EXPECTING IT TO FILL THE LAYER
UIImage *layerImage = [UIImage imageNamed:#"infoScreen"];
CGImageRef image = [layerImage CGImage];
[myLayer setContents:(__bridge id)image];
[myLayer setContentsGravity:kCAGravityCenter]; /* IT WORKS FINE IF I USE setContentsGravity:kCAGravityResizeAspectFill */
This code works fine on a non-iPad retina. However on the Retina iPad, the image is always loaded at twice the actual size (so it appears zoomed in). I'm using the Simulator and iOS 8. What am I doing wrong?
Beging your image processing with
func UIGraphicsBeginImageContextWithOptions(size: CGSize, opaque: Bool, scale: CGFloat)
The last parameter in the above function determines the scaling for the graphics. You can set
this value by retrieving the scale property of the main screen. In swift I would do it this way:
var screen = UIScreen.mainScreen()
var scale = screen.scale
Hope it helps.
Edit: - Code for doing this in swift, you can modify it to suit your need.
UIGraphicsBeginImageContextWithOptions(rect.size, true, 0.0)
var ctx : CGContextRef = UIGraphicsGetCurrentContext()
<UIImage>.drawInRect(rect)
I had this same problem, was solved by setting the contentsScale value on the CALayer - for some reason the default scale on CALayers is always 1.0, even on Retina devices.
i.e.
layer.contentsScale = [UIScreen mainScreen].scale;
Also, if you're drawing a shape using CAShapeLayer and wondering its edges look a little jagged on retina devices, try:
shapeLayer.rasterizationScale = [UIScreen mainScreen].scale;
shapeLayer.shouldRasterize = YES;
I am working on iOS application where I need to capture the view and send MMS to particular person.Its all working fine.But I am facing problem to capture which is not visible (For more clarification I attached image).
I am getting the screen shot of the view which is visible.How to solve the problem? Is there any approach to reach my requirement? The image what I am getting is
I used the code to take screenshot is
UIGraphicsBeginImageContext(webview_pdf.bounds.size);
[webview_pdf.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *pdfImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Good suggestions are appreciable.Thanks in advance.!
Finally found the solution to this
+ (UIImage *) imageFromWebView:(UIWebView *)view
{
// tempframe to reset view size after image was created
CGRect tmpFrame = view.frame;
// set new Frame
CGRect aFrame = view.frame;
aFrame.size.height = [view sizeThatFits:[[UIScreen mainScreen] bounds].size].height;
view.frame = aFrame;
// do image magic
UIGraphicsBeginImageContext([view sizeThatFits:[[UIScreen mainScreen] bounds].size]);
CGContextRef resizedContext = UIGraphicsGetCurrentContext();
[view.layer renderInContext:resizedContext];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// reset Frame of view to origin
view.frame = tmpFrame;
return image;
}
You need to create another view that is the full size of the content. You can add this view off screen and then capture it the same way as you have done here. The reason it is cut off is because the view has only rendered that part of the content.
Currently i am making "traditional" screenshots and combine them using a graphics editor to show the full webpage at once. Is there any more efficient way of making screenshots of a full webpage, just as by using Awesome Screenshot for Google Chrome?
(No, i do not have an iPhone ;)
You have to write it on your own.
Create a fullscreen webView inside your app.
Open page you want to open
Manipulate the property webView.scrollView to move successfully to the bottom of the page.
Capture screenshot every time
If you're on the bottom merge screenshots to one large images.
I believe this is a simplest way and run on the simulator.
See the code below.
-(NSData *)getImageFromView:(UIView *)view // Mine is UIWebView but should work for any
{
NSData *pngImg;
CGFloat max, scale = 1.0;
CGSize viewSize = [view bounds].size;
// Get the size of the the FULL Content, not just the bit that is visible
CGSize size = [view sizeThatFits:CGSizeZero];
// Scale down if on iPad to something more reasonable
max = (viewSize.width > viewSize.height) ? viewSize.width : viewSize.height;
if( max > 960 )
scale = 960/max;
UIGraphicsBeginImageContextWithOptions( size, YES, scale );
// Set the view to the FULL size of the content.
[view setFrame: CGRectMake(0, 0, size.width, size.height)];
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
pngImg = UIImagePNGRepresentation( UIGraphicsGetImageFromCurrentImageContext() );
UIGraphicsEndImageContext();
return pngImg; // Voila an image of the ENTIRE CONTENT, not just visible bit
}
I got this code from this link. Hope it will help you.