1. 程式人生 > >iOS 關於監聽手機截圖,UIView生成UIImage, UIImage裁剪與壓縮的總結

iOS 關於監聽手機截圖,UIView生成UIImage, UIImage裁剪與壓縮的總結

一.  關於監聽手機截圖

1. 背景: 發現商品的售價頁總是被人轉發截圖,為了方便使用者新增截圖分享的小功能

首先要註冊使用者截圖操作的通知

- (void)viewDidLoad {
    [super viewDidLoad];
    //註冊使用者的截圖操作通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(userDidTakeScreenshot:)
                                                 name:UIApplicationUserDidTakeScreenshotNotification 
object:nil]; }

之後人為截圖

// 截圖響應
- (void)userDidTakeScreenshot:(NSNotification *)notification
{
    //人為截圖, 模擬使用者截圖行為, 獲取所截圖片
    _screenshotImg = [UIutils imageWithScreenshot]; // 這裡封裝了一下 獲得圖片就可以取分享啦
    DhshareActionSheetScreenshot *shareAlert = [[DhshareActionSheetScreenshot alloc] init];
    [shareAlert showWithImg:_screenshotImg];
}

人為截圖,在這裡可以對圖片進行一些操作,比如新增自己的APP二維碼啥的類似微博

/**
 *  擷取當前螢幕 並修改
 */
+ (UIImage *)imageWithScreenshot
{
    CGSize imageSize = CGSizeZero;
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if (UIInterfaceOrientationIsPortrait(orientation))
        imageSize 
= [UIScreen mainScreen].bounds.size; else imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width); UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0); CGContextRef context = UIGraphicsGetCurrentContext(); for (UIWindow *window in [[UIApplication sharedApplication] windows]) { CGContextSaveGState(context); CGContextTranslateCTM(context, window.center.x, window.center.y); CGContextConcatCTM(context, window.transform); CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y); if (orientation == UIInterfaceOrientationLandscapeLeft) { CGContextRotateCTM(context, M_PI_2); CGContextTranslateCTM(context, 0, -imageSize.width); }else if (orientation == UIInterfaceOrientationLandscapeRight) { CGContextRotateCTM(context, -M_PI_2); CGContextTranslateCTM(context, -imageSize.height, 0); } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { CGContextRotateCTM(context, M_PI); CGContextTranslateCTM(context, -imageSize.width, -imageSize.height); } if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) { [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES]; } else { [window.layer renderInContext:context]; } CGContextRestoreGState(context); } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }

當然最後不要忘記登出通知,這裡要注意,根據需求來,如果商品詳情頁又可以跳轉到別的商品詳情頁最好這樣登出,

避免跳到別的商品詳情頁多次截圖

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationUserDidTakeScreenshotNotification object:nil];

}

二. UIView生成UIImag

UIView生成UIImage 時可以轉一下jpg格式,這樣圖片不會太大具體引數可以百度,螢幕密度我一般採用0.7;

// UIView生成圖片
+(UIImage*)convertViewToImage:(UIView*)v{
    CGSize s = v.bounds.size;
    // 下面方法,第一個引數表示區域大小。第二個引數表示是否是非透明的。如果需要顯示半透明效果,需要傳NO,否則傳YES。第三個引數就是螢幕密度了
    //    NSLog(@"[UIScreen mainScreen].scale-%f",[UIScreen mainScreen].scale);
    // 3.0 高清圖 分享不了 用2.0即可 或者分享的時候壓縮圖片
    UIGraphicsBeginImageContextWithOptions(s, YES, [UIScreen mainScreen].scale);
    [v.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage*image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    NSData * data = UIImageJPEGRepresentation(image, 0.7);
    UIImage* imagelast = [UIImage imageWithData:data];
    
    return imagelast;
}

三. UIImage的裁剪

// 圖片裁剪
+ (UIImage *)ct_imageFromImage:(UIImage *)image inRect:(CGRect)rect{
    
    //把像 素rect 轉化為 點rect(如無轉化則按原影象素取部分圖片)
    CGFloat scale = [UIScreen mainScreen].scale;
    CGFloat x= rect.origin.x*scale,y=rect.origin.y*scale,w=rect.size.width*scale,h=rect.size.height*scale;
    CGRect dianRect = CGRectMake(x, y, w, h);
    
    //擷取部分圖片並生成新圖片
    CGImageRef sourceImageRef = [image CGImage];
    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, dianRect);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
    
    NSData * data = UIImageJPEGRepresentation(newImage, 0.7);
    UIImage* imagelast = [UIImage imageWithData:data];
    return imagelast;
}

四. UIImage的壓縮

分享圖片時根據分享的應用不同對圖片大小是有限制的,微信是10M,但是qq小一些,

另外小程式分享的話也是有限制的128Kb,當截圖裁剪後無法滿足時就需要壓縮一下

先是密度壓縮然後大小壓縮,一般都可以解決的

// 圖片壓縮
+ (UIImage *)compressImage:(UIImage *)image toByte:(NSUInteger)maxLength {
    // Compress by quality
    CGFloat compression = 0.7;
    //UIImage轉換為NSData
    NSData *data = UIImageJPEGRepresentation(image, compression);
    if (data.length < maxLength){
        return image;
    }
    CGFloat max = 1;
    CGFloat min = 0;
    for (int i = 0; i < 6; ++i) {
        compression = (max + min) / 2;
        data = UIImageJPEGRepresentation(image, compression);
        if (data.length < maxLength * 0.9) {
            min = compression;
        } else if (data.length > maxLength) {
            max = compression;
        } else {
            break;
        }
    }
    UIImage *resultImage = [UIImage imageWithData:data];
    if (data.length < maxLength){
        return resultImage;
    }
    // Compress by size
    NSUInteger lastDataLength = 0;
    while (data.length > maxLength && data.length != lastDataLength) {
        lastDataLength = data.length;
        CGFloat ratio = (CGFloat)maxLength / data.length;
        CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)),
                                 (NSUInteger)(resultImage.size.height * sqrtf(ratio))); // Use NSUInteger to prevent white blank
        UIGraphicsBeginImageContext(size);
        [resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
        resultImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        data = UIImageJPEGRepresentation(resultImage, compression);
    }
    return resultImage;
}

這些是最近APP的截圖分享,小程式分享的關於圖片的總結.希望幫助到需要的人.