Pergunta

Eu estou usando UIImagePickerController para tirar uma foto no modo retrato no iPhone e salvar para a web. A foto aparece no retrato no telefone, mas gira 90 graus na web.

Se eu baixar a foto e olhar para ele em Preview (Mac) ou Photoshop (Mac ou PC) é no retrato novamente. No Windows Picture Viewer (pc) é rodado para paisagem.

Do I necessidade de aplicar uma rotação de transformação para os dados da imagem antes de enviar? Será que eu, em seguida, também precisará remover os meta-dados que está girando-o no Photoshop e na pré-visualização?

Foi útil?

Solução

O problema foi que a rotação imagem foi adicionado à foto como dados EXIF ??não são utilizados pela maioria dos navegadores. Há duas soluções:

  1. Aplicar a rotação no lado do servidor. Eu estava usando Ruby plug-in Paperclip (por Thoughtbot) e só tinha de incluir a opção convertido auto-orientar para o comando has_attached_file no modelo:

    has_attached_file: foto,: convert_options => {: all => '-auto-orient'}

  2. Girar a foto dentro do aplicativo iPhone. Isto foi resolvido em outra pergunta stackoverflow; chamando o href="https://stackoverflow.com/questions/538041/uiimagepickercontroller-camera-preview-is-portrait-in-landscape-app"> método scaleAndRotate substitui os meta-dados de rotação com um imagem transformar, graças à @Squeegy.

Outras dicas

Uma vez que você tirar a foto antes de carregar a imagem para o servidor apenas passar sua imagem levada em um método e sua certamente funciona para você

#pragma mark Rotate
- (UIImage *)scaleAndRotateImage:(UIImage *)image {
    int kMaxResolution = 640; // Or whatever

    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 = roundf(bounds.size.width / ratio);
        }
        else {
            bounds.size.height = kMaxResolution;
            bounds.size.width = roundf(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;
}

Aqui está uma maneira fácil de substituir manualmente os metadados EXIF ??rotação, se a imagem é guardada na orientação correta em MS Windows. No Windows Explorer, clique com o botão direito no arquivo de imagem e selecione "Rodar no sentido horário". Faça isso 4 vezes para girar a imagem a toda a volta, e, em seguida, a imagem terá a orientação correta para todos os sistemas. Então você pode enviar a imagem para o seu servidor web.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top