iOS Görüntü Yönlendirmesinin Garip Davranışı Var


96

Son birkaç haftadır objektif-c'de resimlerle çalışıyorum ve birçok tuhaf davranışı fark ettim. Birincisi, diğer birçok insan gibi, ben de bu sorunu yaşıyorum, kamerayla çekilmiş (veya başka birinin kamerasıyla ve MMS ile çekilmiş) 90 derece döndürülüyor. Dünyada bunun neden olduğundan emin değildim (dolayısıyla sorum ) ama etrafta ucuz bir iş bulabildim.

Bu sefer sorum şu , bu neden oluyor ? Apple görüntüleri neden döndürüyor? Kameramla bir fotoğraf çektiğimde, yukarıda bahsedilen kodumu yapmazsam, fotoğrafı kaydettiğimde döndürülerek kaydedilir. Şimdi, çözümüm birkaç gün öncesine kadar iyiydi.

Uygulamam, bir görüntünün tek tek piksellerini, özellikle de bir PNG'nin alfa kanalını değiştirir (bu nedenle, herhangi bir JPEG dönüşümü senaryom için pencereden atılır). Birkaç gün önce, geçici çözüm kodum sayesinde görüntünün uygulamamda düzgün görüntülenmesine rağmen, algoritmam görüntünün tek tek piksellerini değiştirdiğinde görüntünün döndürüldüğünü düşündüğünü fark ettim. Yani görüntünün üstündeki pikselleri değiştirmek yerine görüntünün yanındaki pikselleri değiştirir (çünkü döndürülmesi gerektiğini düşünür)! Hafızadaki görüntünün nasıl döndürüleceğini çözemiyorum - ideal olarak bu imageOrientationbayrağı hep birlikte silmeyi tercih ederim .

İşte beni şaşırtan başka bir şey daha ... Fotoğrafı çektiğimde imageOrientation3'e ayarlandı. Geçici çözüm kodum bunu anlayacak ve kullanıcının asla fark etmemesi için onu çevirecek kadar akıllı. Ek olarak, görüntüyü kitaplığa kaydetme kodum bunu fark eder, döndürür ve ardından kamera rulosunda düzgün görünmesi için kaydeder.

Bu kod şöyle görünüyor:

NSData* pngdata = UIImagePNGRepresentation (self.workingImage); //PNG wrap 
UIImage* img = [self rotateImageAppropriately:[UIImage imageWithData:pngdata]];   
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);

Bu yeni kaydedilmiş görüntüyü uygulamama yüklediğimde imageOrientation, 0 - tam olarak görmek istediğim şeydir ve rotasyon geçici çözümümün çalıştırılmasına bile gerek yoktur (not: bir kamerayla çekilen görüntülerin aksine internetten görüntüler yüklerken , imageOrientationher zaman 0'dır, mükemmel davranışla sonuçlanır). Bazı nedenlerden dolayı, kaydetme kodum bu imageOrientationbayrağı siliyor gibi görünüyor . Kullanıcı bir fotoğraf çekip uygulamaya ekledikten hemen sonra bu kodu çalmayı ve imageOrientation'ı silmek için kullanmayı umuyordum, ancak işe yaramıyor gibi görünüyor. İle UIImageWriteToSavedPhotosAlbumözel bir şey yapıyor imageOrientationmu?

Bu problem için en iyi çözüm imageOrientation, kullanıcı bir görüntüyü çekmeyi bitirir bitirmez havaya uçmak olur mu. Apple'ın rotasyon davranışının bir nedeni olduğunu varsayıyorum, değil mi? Birkaç kişi bunun bir Apple kusuru olduğunu öne sürdü.

(... henüz kaybolmadıysanız ... Not 2: Yatay bir fotoğraf çektiğimde, her şey tıpkı internetten çekilmiş fotoğraflar gibi mükemmel çalışıyor gibi görünüyor)

DÜZENLE:

İşte bazı görüntüler ve senaryolar gerçekte neye benziyor. Şimdiye kadar yapılan yorumlara dayanarak, bu garip davranış, iyi olduğunu düşündüğüm bir iPhone davranışından daha fazlası gibi görünüyor.

Bu, telefonumla çektiğim fotoğrafın bir resmidir (doğru yönlendirmeye dikkat edin), tam olarak telefonumda fotoğrafı çektiğimde olduğu gibi görünüyor:

İPhone'da çekilmiş gerçek fotoğraf

Resim, kendime e-postayla gönderdikten sonra Gmail’de şöyle görünüyor (Gmail bunu düzgün bir şekilde ele alıyor gibi görünüyor):

Gmail'de göründüğü haliyle fotoğraf

Görüntü, pencerelerde küçük resim olarak şöyle görünür (düzgün işlenmiş gibi görünmüyor):

Windows Küçük Resmi

Ve işte gerçek görüntünün Windows Fotoğraf Görüntüleyicisi ile açıldığında nasıl göründüğü (hala düzgün bir şekilde kullanılmıyor):

Windows Fotoğraf Görüntüleyici Sürümü

Bu soruya yapılan tüm yorumlardan sonra şunu düşünüyorum ... iPhone bir görüntü alıyor ve "Bunu düzgün görüntüleyebilmek için 90 derece döndürülmesi gerekiyor" diyor. Bu bilgi EXIF ​​verilerinde olacaktır. (Düz düşey varsayılana dönmek yerine neden 90 derece döndürülmesi gerektiğini bilmiyorum). Buradan Gmail, EXIF ​​verilerini okuyup analiz edecek ve düzgün bir şekilde görüntüleyecek kadar akıllıdır. Ancak Windows, EXIF ​​verilerini okuyacak kadar akıllı değildir ve bu nedenle görüntüyü yanlış görüntüler . Varsayımlarım doğru mu?


İlginç ... eğer bu doğruysa, neden çekilen görüntüler dik açıya ayarlanmış? Bunun bir iPhone hatası olmadığını biliyorum, çünkü bir arkadaşım (BlackBerry ile) bir resim aldığında ve bana MMS gönderdiğinde benzer bir davranış fark ettim.
Boeckm

Kameranızın meta verileri yazıp onu 90 derece döndürmek için yazdığını görün, bazı işletim sistemleri bu meta verileri okurken diğerleri okumaz.
HarshIT

Oldukça iyi okuma (aşağıdaki @ Hadley'in cevabına bakın - eskiden bir yorumdaydı). Bu yüzden uygulamamın, EXIF ​​verilerini içeren resimleri ve bunları içermeyen resimleri işleyecek kadar akıllı olması gerekiyor ... Hala neden sağ tarafı yukarı bakacak şekilde fotoğraf çektiğimi anlamıyorum, yön bayrağı 90 derece döndürülmesi gerektiğini söylüyor?
Boeckm

Fotoğraf modunuzu Dikey olarak ayarladınız ve kameranızı dik açıya döndürmüyorsunuz veya Manzara modu ayarlıysa ve kamera dik açılı konumda görüntü çekmişse, sensör otomatik olarak yönlendirmeyi uygun olana ayarlayacaktır. Bir göz atın
HarshIT

1
Çözüm, büyük olasılıkla uygulamanızın meta verileri okuması ve görüntüyü döndürmesi ve / veya meta verileri ihtiyaca göre değiştirmesi gerektiğidir.
HarshIT

Yanıtlar:


50

Üzerinde Ar-Ge yaptım ve her görüntü dosyasının meta veri özelliğine sahip olduğunu keşfettim. Meta veriler, görüntünün yönünü belirtiyorsa, bu genellikle Mac dışındaki diğer işletim sistemleri tarafından yok sayılır. Çekilen resimlerin çoğunun meta veri özelliği dik açıya ayarlanmış. Yani Mac onu 90 derece döndürülmüş şekilde gösteriyor. Aynı görüntüyü Windows işletim sisteminde de doğru şekilde görebilirsiniz.

Daha fazla ayrıntı için bu yanıtı okuyun http://graphicssoft.about.com/od/digitalphotography/f/sideways-pictures.htm

resminizin exifini burada http://www.exifviewer.org/ veya http://regex.info/exif.cgi veya http://www.addictivetips.com/internet-tips/view-complete-exif okumayı deneyin -metadata-bilgi-of-any-jpeg-image-çevrimiçi /


1
VAOV! EXIF verilerinde BU KADAR bilgi olduğunu bilmiyordum! regex.info/exif.cgi inanılmaz bir site! Bu gece kesinlikle bu sitede resimlerle oynayacağım. Her senaryoyu test etmem gerekecek, görüntüler doğrudan çekilecek, internetten alınan fotoğraflar, döndürülmüş resimler vb. Çok teşekkürler!
Boeckm

İlk exif bağlantısı şimdi bozuldu ve ikincisi exif.regex.info/exif.cgi olarak güncellendi Cevabı düzenlemeye çalıştım ama @ cj-dennis bir nedenle reddetti.
Ryan

55

Kameradan görüntü aldığımda da aynı sorunu yaşadım, düzeltmek için aşağıdaki kodu koydum .. Buradan scaleAndRotateImage yöntemini ekledim

- (void) imagePickerController:(UIImagePickerController *)thePicker didFinishPickingMediaWithInfo:(NSDictionary *)imageInfo {
            // Images from the camera are always in landscape, so rotate
                    UIImage *image = [self scaleAndRotateImage: [imageInfo objectForKey:UIImagePickerControllerOriginalImage]];
    //then save the image to photo gallery or wherever  
        }


- (UIImage *)scaleAndRotateImage:(UIImage *) image {
    int kMaxResolution = 320;

    CGImageRef imgRef = image.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);


    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);
    if (width > kMaxResolution || height > kMaxResolution) {
        CGFloat ratio = width/height;
        if (ratio > 1) {
            bounds.size.width = kMaxResolution;
            bounds.size.height = bounds.size.width / ratio;
        }
        else {
            bounds.size.height = kMaxResolution;
            bounds.size.width = bounds.size.height * ratio;
        }
    }

    CGFloat scaleRatio = bounds.size.width / width;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = image.imageOrientation;
    switch(orient) {

        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];

    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
        CGContextScaleCTM(context, -scaleRatio, scaleRatio);
        CGContextTranslateCTM(context, -height, 0);
    }
    else {
        CGContextScaleCTM(context, scaleRatio, -scaleRatio);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return imageCopy;
}

3
ScaleAndRotateImage kodunuz neye benziyor? Bir google yaptıktan sonra buradaki ile aynı mı? tartışmalar.apple.com
thread/1537011?start=0&tstart=0

2
VAY ... Haha! Bu son derece iyi çalıştı! Kodu yukarıdaki yorumumda kullandım. Soruma iki harika cevabım var! Sanırım bu, çok büyük bir soru sorduğum anlamına geliyor ... Çok teşekkürler. Biraz derinlemesine test yapacağım, ancak şu ana kadar yön problemi dikey ve yatay olarak çekilen fotoğraflarda harika çalışıyor.
Boeckm

3
Sanırım yönteminizin bir kısmı eksik, ancak bu ve bağlantı hala geri kalanını çözmem ve sonunda görüntü kırpma görünümümün düzgün çalışmasını sağlamam için yeterliydi, bu yüzden teşekkürler :)
Vic Smith


Bu kod bloğu, orijinal görüntünün nasıl göründüğünü koruyor, ancak yönünü yukarı olacak şekilde değiştiriyor mu?
Junchao Gu

20

Bu sefer sorum şu, bu neden oluyor? Apple görüntüleri neden döndürüyor?

Bunun cevabı çok basit. Apple resmi döndürmüyor. Karışıklık burada yatıyor.

CCD kamera dönmediğinden, fotoğrafı her zaman yatay modda çekiyor.

Apple çok akıllıca bir şey yaptı - her zaman görüntüyü döndürmek için harcamak - megabaytlarca veriyi karıştırmak yerine - sadece resmin nasıl çekildiğini etiketleyin.

OpenGL çevirileri çok kolay bir şekilde yapar - böylece VERİLER asla karıştırılmaz - sadece NASIL ÇİZİLİR.

Dolayısıyla yönelim meta verileri.

Kırpmak, yeniden boyutlandırmak vb. İstiyorsanız bu bir sorun haline gelir - ancak ne olduğunu öğrendikten sonra, sadece matrisinizi tanımlarsınız ve her şey yoluna girer.


1
Bu açıklama için teşekkür ederim. Bir kez düşündüğünüzde sağduyu, ancak başka hiçbir Google sonuç bunu açıklamadı.
Dakine83

bir profesör gibi güzel bir açıklama. Teşekkürler!
vkGunasekaran

18

Hızlı kopyala / yapıştır Dilip'in mükemmel cevabının hızlı çevirisi .

import Darwin

class func rotateCameraImageToProperOrientation(imageSource : UIImage, maxResolution : CGFloat) -> UIImage {

    let imgRef = imageSource.CGImage;

    let width = CGFloat(CGImageGetWidth(imgRef));
    let height = CGFloat(CGImageGetHeight(imgRef));

    var bounds = CGRectMake(0, 0, width, height)

    var scaleRatio : CGFloat = 1
    if (width > maxResolution || height > maxResolution) {

        scaleRatio = min(maxResolution / bounds.size.width, maxResolution / bounds.size.height)
        bounds.size.height = bounds.size.height * scaleRatio
        bounds.size.width = bounds.size.width * scaleRatio
    }

    var transform = CGAffineTransformIdentity
    let orient = imageSource.imageOrientation
    let imageSize = CGSizeMake(CGFloat(CGImageGetWidth(imgRef)), CGFloat(CGImageGetHeight(imgRef)))


    switch(imageSource.imageOrientation) {
    case .Up :
        transform = CGAffineTransformIdentity

    case .UpMirrored :
        transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
        transform = CGAffineTransformScale(transform, -1.0, 1.0);

    case .Down :
        transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
        transform = CGAffineTransformRotate(transform, CGFloat(M_PI));

    case .DownMirrored :
        transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
        transform = CGAffineTransformScale(transform, 1.0, -1.0);

    case .Left :
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width;
        bounds.size.width = storedHeight;
        transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
        transform = CGAffineTransformRotate(transform, 3.0 * CGFloat(M_PI) / 2.0);

    case .LeftMirrored :
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width;
        bounds.size.width = storedHeight;
        transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
        transform = CGAffineTransformScale(transform, -1.0, 1.0);
        transform = CGAffineTransformRotate(transform, 3.0 * CGFloat(M_PI) / 2.0);

    case .Right :
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width;
        bounds.size.width = storedHeight;
        transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
        transform = CGAffineTransformRotate(transform, CGFloat(M_PI) / 2.0);

    case .RightMirrored :
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width;
        bounds.size.width = storedHeight;
        transform = CGAffineTransformMakeScale(-1.0, 1.0);
        transform = CGAffineTransformRotate(transform, CGFloat(M_PI) / 2.0);

    default : ()
    }

    UIGraphicsBeginImageContext(bounds.size)
    let context = UIGraphicsGetCurrentContext()

    if orient == .Right || orient == .Left {
        CGContextScaleCTM(context, -scaleRatio, scaleRatio);
        CGContextTranslateCTM(context, -height, 0);
    } else {
        CGContextScaleCTM(context, scaleRatio, -scaleRatio);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);
    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);

    let imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return imageCopy;
}

1
Teşekkürler, ama "let oran = genişlik / yükseklik" nedir? için kullanılır? Oran kullanan herhangi bir yer göremiyorum {}
Pengzhi Zhou

16

Dilip'in cevabının güvenlik kontrollerini içeren Swift 4 versiyonu .

public static func rotateCameraImageToProperOrientation(imageSource : UIImage, maxResolution : CGFloat = 320) -> UIImage? {

    guard let imgRef = imageSource.cgImage else {
        return nil
    }

    let width = CGFloat(imgRef.width)
    let height = CGFloat(imgRef.height)

    var bounds = CGRect(x: 0, y: 0, width: width, height: height)

    var scaleRatio : CGFloat = 1
    if (width > maxResolution || height > maxResolution) {

        scaleRatio = min(maxResolution / bounds.size.width, maxResolution / bounds.size.height)
        bounds.size.height = bounds.size.height * scaleRatio
        bounds.size.width = bounds.size.width * scaleRatio
    }

    var transform = CGAffineTransform.identity
    let orient = imageSource.imageOrientation
    let imageSize = CGSize(width: CGFloat(imgRef.width), height: CGFloat(imgRef.height))

    switch(imageSource.imageOrientation) {
    case .up:
        transform = .identity
    case .upMirrored:
        transform = CGAffineTransform
            .init(translationX: imageSize.width, y: 0)
            .scaledBy(x: -1.0, y: 1.0)
    case .down:
        transform = CGAffineTransform
            .init(translationX: imageSize.width, y: imageSize.height)
            .rotated(by: CGFloat.pi)
    case .downMirrored:
        transform = CGAffineTransform
            .init(translationX: 0, y: imageSize.height)
            .scaledBy(x: 1.0, y: -1.0)
    case .left:
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width;
        bounds.size.width = storedHeight;
        transform = CGAffineTransform
            .init(translationX: 0, y: imageSize.width)
            .rotated(by: 3.0 * CGFloat.pi / 2.0)
    case .leftMirrored:
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width;
        bounds.size.width = storedHeight;
        transform = CGAffineTransform
            .init(translationX: imageSize.height, y: imageSize.width)
            .scaledBy(x: -1.0, y: 1.0)
            .rotated(by: 3.0 * CGFloat.pi / 2.0)
    case .right :
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width;
        bounds.size.width = storedHeight;
        transform = CGAffineTransform
            .init(translationX: imageSize.height, y: 0)
            .rotated(by: CGFloat.pi / 2.0)
    case .rightMirrored:
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width;
        bounds.size.width = storedHeight;
        transform = CGAffineTransform
            .init(scaleX: -1.0, y: 1.0)
            .rotated(by: CGFloat.pi / 2.0)
    }

    UIGraphicsBeginImageContext(bounds.size)
    if let context = UIGraphicsGetCurrentContext() {
        if orient == .right || orient == .left {
            context.scaleBy(x: -scaleRatio, y: scaleRatio)
            context.translateBy(x: -height, y: 0)
        } else {
            context.scaleBy(x: scaleRatio, y: -scaleRatio)
            context.translateBy(x: 0, y: -height)
        }

        context.concatenate(transform)
        context.draw(imgRef, in: CGRect(x: 0, y: 0, width: width, height: height))
    }

    let imageCopy = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return imageCopy
}

(bounds.size.height, bounds.size.width) = (bounds.size.width, bounds.size.height)Depolama olarak değişken oluşturmadan da yapabilirsiniz .
Almas Sapargali

Bazen, görüntüyü ölçeklendirdikten sonra alt kısmında beyaz bir çizginin görünmesi sorunu yaşadım. Bunun nedeni, CGFloat'ın yeterince kesin olmamasıdır. Bunu bounds.size.height.round()ve ile düzelttimbounds.size.width.round()
ndreisg

13

İPhone / iPad tarafından oluşturulan herhangi bir görüntü, gerçek yönü belirten EXIF ​​Oryantasyon etiketi (Exif.Image.Orientation) ile Yatay Sol olarak kaydedilir.

Aşağıdaki değerlere sahiptir: 1: Yatay Sol 6: Dikey Normal 3: Yatay Sağ 4: Dikey Baş Aşağı

IOS'ta, EXIF ​​bilgileri düzgün bir şekilde okunur ve görüntüler, çekildikleri şekilde görüntülenir. Ancak Windows'ta EXIF ​​bilgisi KULLANILMAZ.

Bu görsellerden birini GIMP'de açarsanız, görüntünün döndürme bilgisine sahip olduğu söylenecektir.


8

Xamarin kullanan diğer herkes için burada Dilip'in harika cevabının bir C # çevirisi ve Swift çevirisi için thattyson'a bir teşekkürler .

public static UIImage RotateCameraImageToProperOrientation(UIImage imageSource, nfloat maxResolution) {

    var imgRef = imageSource.CGImage;

    var width = (nfloat)imgRef.Width;
    var height = (nfloat)imgRef.Height;

    var bounds = new CGRect(0, 0, width, height);

    nfloat scaleRatio = 1;

    if (width > maxResolution || height > maxResolution) 
    {
        scaleRatio = (nfloat)Math.Min(maxResolution / bounds.Width, maxResolution / bounds.Height);
        bounds.Height = bounds.Height * scaleRatio;
        bounds.Width = bounds.Width * scaleRatio;
    }

    var transform = CGAffineTransform.MakeIdentity();
    var orient = imageSource.Orientation;
    var imageSize = new CGSize(imgRef.Width, imgRef.Height);
    nfloat storedHeight;

    switch(imageSource.Orientation) {
        case UIImageOrientation.Up:
            transform = CGAffineTransform.MakeIdentity();
            break;

        case UIImageOrientation.UpMirrored :
            transform = CGAffineTransform.MakeTranslation(imageSize.Width, 0.0f);
            transform = CGAffineTransform.Scale(transform, -1.0f, 1.0f);
            break;

        case UIImageOrientation.Down :
            transform = CGAffineTransform.MakeTranslation(imageSize.Width, imageSize.Height);
            transform = CGAffineTransform.Rotate(transform, (nfloat)Math.PI);
            break;

        case UIImageOrientation.DownMirrored :
            transform = CGAffineTransform.MakeTranslation(0.0f, imageSize.Height);
            transform = CGAffineTransform.Scale(transform, 1.0f, -1.0f);
            break;

        case UIImageOrientation.Left:
            storedHeight = bounds.Height;
            bounds.Height = bounds.Width;
            bounds.Width = storedHeight;
            transform = CGAffineTransform.MakeTranslation(0.0f, imageSize.Width);
            transform = CGAffineTransform.Rotate(transform, 3.0f * (nfloat)Math.PI / 2.0f);
            break;

        case UIImageOrientation.LeftMirrored :
            storedHeight = bounds.Height;
            bounds.Height = bounds.Width;
            bounds.Width = storedHeight;
            transform = CGAffineTransform.MakeTranslation(imageSize.Height, imageSize.Width);
            transform = CGAffineTransform.Scale(transform, -1.0f, 1.0f);
            transform = CGAffineTransform.Rotate(transform, 3.0f * (nfloat)Math.PI / 2.0f);
            break;

        case UIImageOrientation.Right :
            storedHeight = bounds.Height;
            bounds.Height = bounds.Width;
            bounds.Width = storedHeight;
            transform = CGAffineTransform.MakeTranslation(imageSize.Height, 0.0f);
            transform = CGAffineTransform.Rotate(transform, (nfloat)Math.PI / 2.0f);
            break;

        case UIImageOrientation.RightMirrored :
            storedHeight = bounds.Height;
            bounds.Height = bounds.Width;
            bounds.Width = storedHeight;
            transform = CGAffineTransform.MakeScale(-1.0f, 1.0f);
            transform = CGAffineTransform.Rotate(transform, (nfloat)Math.PI / 2.0f);
            break;

        default :
            break;
    }

    UIGraphics.BeginImageContext(bounds.Size);
    var context = UIGraphics.GetCurrentContext();

    if (orient == UIImageOrientation.Right || orient == UIImageOrientation.Left) {
        context.ScaleCTM(-scaleRatio, scaleRatio);
        context.TranslateCTM(-height, 0);
    } else {
        context.ScaleCTM(scaleRatio, -scaleRatio);
        context.TranslateCTM(0, -height);
    }

    context.ConcatCTM(transform);
    context.DrawImage(new CGRect(0, 0, width, height), imgRef);

    var imageCopy = UIGraphics.GetImageFromCurrentImageContext();
    UIGraphics.EndImageContext();

    return imageCopy;
}

Bu, bununla oynayarak saatler geçirdikten sonra sorunumun çözülmesine yardımcı oldu! Xamarin'in artık bir Microsoft ürünü olduğu için bunun için bazı yerleşik desteğe sahip olmaması inanılmaz.
Sami.C

4

Bu soruyla karşılaştım çünkü benzer bir sorun yaşıyordum ama Swift kullanıyordum. Diğer Swift geliştiricileri için benim için çalışan cevaba bağlantı vermek istedim: https://stackoverflow.com/a/26676578/3904581

Sorunu verimli bir şekilde düzelten bir Swift pasajı:

let orientedImage = UIImage(CGImage: initialImage.CGImage, scale: 1, orientation: initialImage.imageOrientation)!

Çok basit. Bir satır kod. Sorun çözüldü.


Bu benim için işe yaramadı, bu çözümü kullandım: stackoverflow.com/a/27775741/945247
Leon


0

Swift 3 için hızla yeniden düzenlendi (birisi test edip her şeyin yolunda gittiğini onaylayabilir mi?):

static func rotateCameraImageToProperOrientation(imageSource : UIImage, maxResolution : CGFloat) -> UIImage {
    let imgRef = imageSource.cgImage

    let width = CGFloat(imgRef!.width)
    let height = CGFloat(imgRef!.height)

    var bounds = CGRect(x: 0, y: 0, width: width, height: height)

    var scaleRatio : CGFloat = 1
    if width > maxResolution || height > maxResolution {

        scaleRatio = min(maxResolution / bounds.size.width, maxResolution / bounds.size.height)
        bounds.size.height = bounds.size.height * scaleRatio
        bounds.size.width = bounds.size.width * scaleRatio
    }

    var transform = CGAffineTransform.identity
    let orient = imageSource.imageOrientation
    let imageSize = CGSize(width: imgRef!.width, height: imgRef!.height)

    switch imageSource.imageOrientation {
    case .up :
        transform = CGAffineTransform.identity

    case .upMirrored :
        transform = CGAffineTransform(translationX: imageSize.width, y: 0)
        transform = transform.scaledBy(x: -1, y: 1)

    case .down :
        transform = CGAffineTransform(translationX: imageSize.width, y: imageSize.height)
        transform = transform.rotated(by: CGFloat.pi)

    case .downMirrored :
        transform = CGAffineTransform(translationX: 0, y: imageSize.height)
        transform = transform.scaledBy(x: 1, y: -1)

    case .left :
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width
        bounds.size.width = storedHeight
        transform = CGAffineTransform(translationX: 0, y: imageSize.width)
        transform = transform.rotated(by: 3.0 * CGFloat.pi / 2.0)

    case .leftMirrored :
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width
        bounds.size.width = storedHeight
        transform = CGAffineTransform(translationX: imageSize.height, y: imageSize.width)
        transform = transform.scaledBy(x: -1, y: 1)
        transform = transform.rotated(by: 3.0 * CGFloat.pi / 2.0)

    case .right :
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width
        bounds.size.width = storedHeight
        transform = CGAffineTransform(translationX: imageSize.height, y: 0)
        transform = transform.rotated(by: CGFloat.pi / 2.0)

    case .rightMirrored :
        let storedHeight = bounds.size.height
        bounds.size.height = bounds.size.width
        bounds.size.width = storedHeight
        transform = CGAffineTransform(scaleX: -1, y: 1)
        transform = transform.rotated(by: CGFloat.pi / 2.0)

    }

    UIGraphicsBeginImageContext(bounds.size)
    let context = UIGraphicsGetCurrentContext()

    if orient == .right || orient == .left {

        context!.scaleBy(x: -scaleRatio, y: scaleRatio)
        context!.translateBy(x: -height, y: 0)
    } else {
        context!.scaleBy(x: scaleRatio, y: -scaleRatio)
        context!.translateBy(x: 0, y: -height)
    }

    context!.concatenate(transform)
    context!.draw(imgRef!, in: CGRect(x: 0, y: 0, width: width, height: height))

    let imageCopy = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return imageCopy!
}

0

İşte Dilip'in harika cevabının Swift3 versiyonu

func rotateCameraImageToProperOrientation(imageSource : UIImage, maxResolution : CGFloat) -> UIImage {
    let imgRef = imageSource.cgImage!;

    let width = CGFloat(imgRef.width);
    let height = CGFloat(imgRef.height);

    var bounds = CGRect(x: 0, y: 0, width: width, height: height)

    var scaleRatio : CGFloat = 1
    if (width > maxResolution || height > maxResolution) {
        scaleRatio = min(maxResolution / bounds.size.width, maxResolution / bounds.size.height)
        bounds.size.height = bounds.size.height * scaleRatio
        bounds.size.width = bounds.size.width * scaleRatio
    }

    var transform = CGAffineTransform.identity
    let orient = imageSource.imageOrientation
    let imageSize = CGSize(width: width, height: height)


    switch(imageSource.imageOrientation) {
        case .up :
            transform = CGAffineTransform.identity

        case .upMirrored :
            transform = CGAffineTransform(translationX: imageSize.width, y: 0.0);
            transform = transform.scaledBy(x: -1, y: 1);

        case .down :
            transform = CGAffineTransform(translationX: imageSize.width, y: imageSize.height);
            transform = transform.rotated(by: CGFloat(Double.pi));

        case .downMirrored :
            transform = CGAffineTransform(translationX: 0.0, y: imageSize.height);
            transform = transform.scaledBy(x: 1, y: -1);

        case .left :
            let storedHeight = bounds.size.height
            bounds.size.height = bounds.size.width;
            bounds.size.width = storedHeight;
            transform = CGAffineTransform(translationX: 0.0, y: imageSize.width);
            transform = transform.rotated(by: 3.0 * CGFloat(Double.pi) / 2.0);

        case .leftMirrored :
            let storedHeight = bounds.size.height
            bounds.size.height = bounds.size.width;
            bounds.size.width = storedHeight;
            transform = CGAffineTransform(translationX: imageSize.height, y: imageSize.width);
            transform = transform.scaledBy(x: -1, y: 1);
            transform = transform.rotated(by: 3.0 * CGFloat(Double.pi) / 2.0);

        case .right :
            let storedHeight = bounds.size.height
            bounds.size.height = bounds.size.width;
            bounds.size.width = storedHeight;
            transform = CGAffineTransform(translationX: imageSize.height, y: 0.0);
            transform = transform.rotated(by: CGFloat(Double.pi) / 2.0);

        case .rightMirrored :
            let storedHeight = bounds.size.height
            bounds.size.height = bounds.size.width;
            bounds.size.width = storedHeight;
            transform = CGAffineTransform(scaleX: -1.0, y: 1.0);
            transform = transform.rotated(by: CGFloat(Double.pi) / 2.0);
    }

    UIGraphicsBeginImageContext(bounds.size)
    let context = UIGraphicsGetCurrentContext()!

    if orient == .right || orient == .left {
        context.scaleBy(x: -scaleRatio, y: scaleRatio);
        context.translateBy(x: -height, y: 0);
    } else {
        context.scaleBy(x: scaleRatio, y: -scaleRatio);
        context.translateBy(x: 0, y: -height);
    }

    context.concatenate(transform);
    context.draw(imgRef, in: CGRect(x: 0, y: 0, width: width, height: height))

    let imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return imageCopy!;
}

-3

Görüntü formatını .jpeg olarak değiştirmeyi deneyin. Bu benim için çalıştı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.