2010-06-27 31 views
15

Tôi đang cố gắng tìm hiểu xem có cách nào phản chiếu hình ảnh không. Ví dụ, chụp một bức ảnh khuôn mặt của một ai đó và sau đó cắt nó thành một nửa và cho thấy khuôn mặt của họ trông như thế nào với mỗi bên được nhân đôi. Dường như không có bất kỳ thủ thuật nào như thế này trong các hàm CGAffineTransform. Chuyên gia đồ họa xin vui lòng giúp đỡ !!!Làm cách nào để phản chiếu hình ảnh UIImage từ UIImagePickerController

Trả lời

34

Bí quyết cơ bản ở đây là sử dụng phép biến đổi tỷ lệ về trục X hoặc Y với hệ số là -1. Ví dụ, bạn có thể sử dụng để tạo ra một "lật về trục ngang" transform:

CGAffineTransform transform = CGAffineTransformScale(transform, -1, 1); 

Sau đó, bạn có thể thiết lập transform tài sản trên một UIImageView để lật hình ảnh được giao, hoặc nối nó với một chuyển đổi để làm hiệu ứng phức tạp hơn. Để có được hiệu ứng chính xác mà bạn mô tả, bạn có thể cần phải viết một số mã vẽ tùy chỉnh để vẽ hình ảnh ban đầu của bạn vào một ngữ cảnh, sau đó phủ một nửa đã lật lên trên nó. Điều này là tương đối đơn giản trong Core Graphics.

+4

hoặc sử dụng CGAffineTransformMakeScale ví dụ picker.cameraViewTransform = CGAffineTransformMakeScale (-1, 1) // nhanh chóng – khunshan

+1

Tuyệt vời! Tôi đã sử dụng 'myImageView.transform = CGAffineTransformMakeScale (-1, 1);' –

19

Nếu bạn chỉ có kế hoạch hỗ trợ 4.0+

UIImageOrientation flippedOrientation = UIImageOrientationUpMirrored; 
switch (image.imageOrientation) { 
    case UIImageOrientationUp: break; 
    case UIImageOrientationDown: flippedOrientation = UIImageOrientationDownMirrored; break; 
    // ... 
} 
UIImage * flippedImage = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:flippedOrientation]; 
12

Bạn có thể nghĩ, tại sao bận tâm với câu lệnh switch outrageously lâu?

? UIImage *flip = [UIImage imageWithCGImage:image.CGImage 
?          scale:image.scale 
?        orientation:(image.imageOrientation + 4) % 8]; 

Và nếu bạn có một cái nhìn tại enum bạn có thể thấy rằng mô-đun số học sẽ làm gì:

typedef NS_ENUM(NSInteger, UIImageOrientation) { 
    UIImageOrientationUp,   // default orientation 
    UIImageOrientationDown,   // 180 deg rotation 
    UIImageOrientationLeft,   // 90 deg CCW 
    UIImageOrientationRight,   // 90 deg CW 
    UIImageOrientationUpMirrored, // as above but image mirrored along other axis. horizontal flip 
    UIImageOrientationDownMirrored, // horizontal flip 
    UIImageOrientationLeftMirrored, // vertical flip 
    UIImageOrientationRightMirrored, // vertical flip 
}; 

Nhưng mã này là quá thông minh. Thay vào đó, bạn nên viết một hàm với câu lệnh chuyển đổi rõ ràng. Ví dụ.

UIImageOrientation mirroredImageOrientation(UIImageOrientation orientation) { 
    switch(orientation) { 
     case UIImageOrientationUp: return UIImageOrientationUpMirrored; 
     case UIImageOrientationDown: return UIImageOrientationDownMirrored; 
     case UIImageOrientationLeft: return UIImageOrientationLeftMirrored; 
     case UIImageOrientationRight: return UIImageOrientationRightMirrored; 
     case UIImageOrientationUpMirrored: return UIImageOrientationUp; 
     case UIImageOrientationDownMirrored: return UIImageOrientationDown; 
     case UIImageOrientationLeftMirrored: return UIImageOrientationLeft; 
     case UIImageOrientationRightMirrored: return UIImageOrientationRight; 
     default: return orientation; 
    } 
} 

Và sử dụng các chức năng như thế này:

UIImage *flip = [UIImage imageWithCGImage:image.CGImage 
            scale:image.scale 
           orientation:mirroredImageOrientation(image.imageOrientation)]; 

Tôi đã thêm dấu hỏi để chỉ ra vấn đề, mã mùi. Tương tự như The Practice of Programming

+1

Thực ra nếu câu trả lời của bạn có vẻ tốt, nó không có trong mọi trường hợp. ví dụ: nếu bạn muốn làm lật ngang nhưng định hướng hình ảnh của bạn là phải, bạn phải làm LeftMirrored, gây ra RightMirrored sẽ cho flip dọc. – AncAinu

+0

Đi từ không được nhân đôi đến nhân đôi sẽ phản chiếu theo chiều ngang hình ảnh, từ góc nhìn của bạn ngồi xuống ghế của bạn. (Bạn nói đúng là từ góc nhìn của hình ảnh nó sẽ lật theo chú thích trong enum.) Nếu các khuôn mặt được định hướng theo hướng thích hợp (đỉnh đầu đến đỉnh của hình ảnh) thì tất cả các phép biến đổi từ không được nhân đôi đến được nhân đôi sẽ lật mặt đó theo chiều ngang (tức là dọc theo trục thẳng đứng). Tài liệu về UIImageOrientation: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/#//apple_ref/c/tdef/UIImageOrientation. – sabalaba

+0

Tôi đã chỉnh sửa câu trả lời của mình để đề xuất sử dụng câu lệnh chuyển đổi rõ ràng. Ai biết được điều gì sẽ xảy ra trên đường. Có lẽ Apple sẽ thay đổi thứ tự của enum trong trường hợp phiên bản số học mô-đun trở nên không chính xác. – sabalaba

5

Không có câu trả lời nào ở trên, trả lời một phần câu hỏi đang phản chiếu một nửa hình ảnh không lật toàn bộ hình ảnh. Trộn các giải pháp dẫn đến chức năng mẫu sau đây bạn có thể sử dụng như một phạm trù như UIImage + Mirroring:

(UIImage *) horizontalMirror { 
    UIImageOrientation flippedOrientation = UIImageOrientationUpMirrored; 
    switch (self.imageOrientation) { 
     case UIImageOrientationUp: break; 
     case UIImageOrientationDown: flippedOrientation = UIImageOrientationDownMirrored; break; 
    } 
    UIImage * flippedImage = [UIImage imageWithCGImage:self.CGImage scale:1.0 orientation:flippedOrientation]; 

    CGImageRef inImage = self.CGImage; 
    CGContextRef ctx = CGBitmapContextCreate(NULL, 
              CGImageGetWidth(inImage), 
              CGImageGetHeight(inImage), 
              CGImageGetBitsPerComponent(inImage), 
              CGImageGetBytesPerRow(inImage), 
              CGImageGetColorSpace(inImage), 
              CGImageGetBitmapInfo(inImage) 
              ); 
    CGRect cropRect = CGRectMake(flippedImage.size.width/2, 0, flippedImage.size.width/2, flippedImage.size.height); 
    CGImageRef TheOtherHalf = CGImageCreateWithImageInRect(flippedImage.CGImage, cropRect); 
    CGContextDrawImage(ctx, CGRectMake(0, 0, CGImageGetWidth(inImage), CGImageGetHeight(inImage)), inImage); 

    CGAffineTransform transform = CGAffineTransformMakeTranslation(flippedImage.size.width, 0.0); 
    transform = CGAffineTransformScale(transform, -1.0, 1.0); 
    CGContextConcatCTM(ctx, transform); 

    CGContextDrawImage(ctx, cropRect, TheOtherHalf); 

    CGImageRef imageRef = CGBitmapContextCreateImage(ctx); 
    CGContextRelease(ctx); 
    UIImage *finalImage = [UIImage imageWithCGImage:imageRef]; 
    CGImageRelease(imageRef); 

    return finalImage; 
} 
+0

Cảm ơn nó đã làm việc – ChanWarde

Các vấn đề liên quan