问题
I'm currently working on a possibility to print the content of a view via Airprint. For this feature I'm creating a UIImage from the view and send it to UIPrintInteractionController.
The problem is that the image is resized to the full resolution of the paper and not it's original size (approx. 300x500px). Does anybody know how to create a proper page from my image.
Here is the code:
/** Create UIImage from UIScrollView**/
-(UIImage*)printScreen{
UIImage* img = 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);
scrollView.backgroundColor = [UIColor whiteColor];
[scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
img = UIGraphicsGetImageFromCurrentImageContext();
scrollView.contentOffset = savedContentOffset;
scrollView.frame = savedFrame;
scrollView.backgroundColor = [UIColor clearColor];
}
UIGraphicsEndImageContext();
return img;
}
/** Print view content via AirPrint **/
-(void)doPrint{
if ([UIPrintInteractionController isPrintingAvailable])
{
UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
UIImage *image = [(ReservationOverView*)self.view printScreen];
NSData *myData = [NSData dataWithData:UIImagePNGRepresentation(image)];
if(pic && [UIPrintInteractionController canPrintData: myData] ) {
pic.delegate =(id<UIPrintInteractionControllerDelegate>) self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputPhoto;
printInfo.jobName = [NSString stringWithFormat:@"Reservation-%@",self.reservation.reservationID];
printInfo.duplex = UIPrintInfoDuplexNone;
pic.printInfo = printInfo;
pic.showsPageRange = YES;
pic.printingItem = myData;
//pic.delegate = self;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if (!completed && error) {
NSLog(@"FAILED! due to error in domain %@ with error code %u", error.domain, error.code);
}
};
[pic presentAnimated:YES completionHandler:completionHandler];
}
}
}
I've tried to resize the image manually, but this does not work properly.
回答1:
I've found this sample code on Apple:
https://developer.apple.com/library/ios/samplecode/PrintPhoto/Listings/Classes_PrintPhotoPageRenderer_m.html#//apple_ref/doc/uid/DTS40010366-Classes_PrintPhotoPageRenderer_m-DontLinkElementID_6
And it looks like the proper way to size an image for printing (so it doesn't fill the entire page) is to implement your own UIPrintPageRenderer and implement:
- (void)drawPageAtIndex:(NSInteger)pageIndex inRect:(CGRect)printableRect
The printableRect will tell you the size of the paper and you can scale it down to however much you want (presumably by calculating some DPI).
Update: I ended up implementing my own ImagePageRenderer:
- (void)drawPageAtIndex:(NSInteger)pageIndex inRect:(CGRect)printableRect
{
if( self.image )
{
CGSize printableAreaSize = printableRect.size;
// Apple uses 72dpi by default for printing images. This
// renders out the image to be giant. Instead, we should
// resize our image to our desired dpi.
CGFloat dpiScale = kAppleDPI / self.dpi;
CGFloat imageWidth = self.image.size.width * dpiScale;
CGFloat imageHeight = self.image.size.height * dpiScale;
// scale image if paper is too small
BOOL scaleImage = printableAreaSize.width < imageWidth || printableAreaSize.height < imageHeight;
if( scaleImage )
{
CGFloat widthScale = (CGFloat)printableAreaSize.width / imageWidth;
CGFloat heightScale = (CGFloat)printableAreaSize.height / imageHeight;
// Choose smaller scale so there's no clipping
CGFloat scale = widthScale < heightScale ? widthScale : heightScale;
imageWidth *= scale;
imageHeight *= scale;
}
// If you want to center vertically, horizontally, or both,
// modify the origin below.
CGRect destRect = CGRectMake( printableRect.origin.x,
printableRect.origin.y,
imageWidth,
imageHeight );
// Use UIKit to draw the image to destRect.
[self.image drawInRect:destRect];
}
else
{
NSLog( @"no image to print" );
}
}
回答2:
UIImage *image = [UIImage imageNamed:@"myImage"];
[image drawInRect: destinationRect];
UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIImageWriteToSavedPhotosAlbum(image,nil,nil,nil);
The destinationRect will be sized according to the dimensions of the downsized version.
来源:https://stackoverflow.com/questions/10231145/resize-uiimage-for-uiprintinteractioncontroller