iPhone imagens da câmera são giradas quando carregado para web
-
22-07-2019 - |
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?
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:
-
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'}
-
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
Aqui está uma solução para CarrierWavew / MiniMagick: http: //carrierwave.rubyforge .org / rdoc / aulas / CarrierWave / MiniMagick.html
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.