Nas últimas semanas, tenho trabalhado com imagens em objetiva-c e percebido muitos comportamentos estranhos. Primeiro, como muitas outras pessoas, tenho tido esse problema onde as imagens tiradas com a câmera (ou tiradas com a câmera de outra pessoa e MMS para mim) são giradas em 90 graus. Eu não tinha certeza de por que isso estava acontecendo (daí minha pergunta ), mas consegui encontrar uma solução barata.
Minha pergunta desta vez é por que isso está acontecendo ? Por que a Apple está girando as imagens? Quando tiro uma foto com a câmera voltada para cima, a menos que execute o código mencionado acima, quando salvo a foto, ela é salva girada. Agora, minha solução alternativa estava bem até alguns dias atrás.
Meu aplicativo modifica pixels individuais de uma imagem, especificamente o canal alfa de um PNG (para que qualquer conversão JPEG seja jogada fora da janela para o meu cenário). Há alguns dias, percebi que, embora a imagem seja exibida corretamente em meu aplicativo graças ao meu código de solução alternativa, quando meu algoritmo modifica os pixels individuais da imagem, ele pensa que a imagem está girada. Então, ao invés de modificar os pixels na parte superior da imagem, ele modifica os pixels na lateral da imagem (porque ele acha que deveria ser girado)! Não consigo descobrir como girar a imagem na memória - o ideal é que eu prefira simplesmente apagar imageOrientation
toda essa bandeira.
Aqui está outra coisa que também está me confundindo ... Quando eu tiro a foto, o imageOrientation
é definido como 3. Meu código de solução alternativa é inteligente o suficiente para perceber isso e virá-lo para que o usuário nunca perceba. Além disso, meu código para salvar a imagem na biblioteca percebe isso, vira e salva para que apareça no rolo da câmera corretamente.
Esse código é assim:
NSData* pngdata = UIImagePNGRepresentation (self.workingImage); //PNG wrap
UIImage* img = [self rotateImageAppropriately:[UIImage imageWithData:pngdata]];
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
Quando eu carrego essa imagem recém-salva em meu aplicativo, o imageOrientation
é 0 - exatamente o que eu quero ver, e minha solução alternativa de rotação nem precisa ser executada (nota: ao carregar imagens da internet em oposição a imagens tiradas com uma câmera , o imageOrientation
é sempre 0, resultando em comportamento perfeito). Por algum motivo, meu código de salvamento parece apagar esse imageOrientation
sinalizador. Eu esperava apenas roubar esse código e usá-lo para limpar minha imageOrientation assim que o usuário tirar uma foto e adicioná-la ao aplicativo, mas não parece funcionar. Faz UIImageWriteToSavedPhotosAlbum
algo especial com imageOrientation
?
A melhor solução para esse problema seria simplesmente explodir imageOrientation
assim que o usuário terminar de tirar uma imagem. Presumo que a Apple tenha o comportamento de rotação feito por um motivo, certo? Algumas pessoas sugeriram que este é um defeito da Apple.
(... se você ainda não está perdido ... Obs2: Quando tiro uma foto horizontal, tudo parece funcionar perfeitamente, assim como as fotos tiradas da internet)
EDITAR:
Aqui estão algumas das imagens e cenários reais. Com base nos comentários até agora, parece que esse comportamento estranho é mais do que apenas um comportamento do iPhone, o que eu acho bom.
Esta é uma foto da foto que tirei com meu telefone (observe a orientação correta), ela aparece exatamente como no meu telefone quando tirei a foto:
Esta é a aparência da imagem no Gmail depois que eu a enviei por e-mail para mim mesmo (parece que o Gmail a lida corretamente):
Aqui está a aparência da imagem como uma miniatura no Windows (não parece que foi tratada corretamente):
E aqui está a aparência da imagem real quando aberta com o Windows Photo Viewer (ainda não tratada corretamente):
Depois de todos os comentários sobre esta questão, eis o que estou pensando ... O iPhone pega uma imagem e diz "para exibir isso corretamente, ela precisa ser girada 90 graus". Essas informações estariam nos dados EXIF. (Por que ele precisa ser girado 90 graus, em vez de padronizar para a vertical, eu não sei). A partir daqui, o Gmail é inteligente o suficiente para ler e analisar os dados EXIF e exibi-los corretamente. O Windows, entretanto, não é inteligente o suficiente para ler os dados EXIF e, portanto, exibe a imagem incorretamente . Minhas suposições estão corretas?
fonte
Respostas:
Eu fiz P&D nele e descobri que todo arquivo de imagem tem propriedade de metadados. Se os metadados especificam a orientação da imagem, que geralmente é ignorada por outros sistemas operacionais, exceto Mac. A maioria das imagens tiradas tem suas propriedades de metadados configuradas em ângulo reto. Então Mac mostra a maneira girada de 90 graus. Você pode ver a mesma imagem de maneira adequada no sistema operacional Windows.
Para mais detalhes, leia esta resposta http://graphicssoft.about.com/od/digitalphotography/f/sideways-pictures.htm
tente ler o exif de sua imagem aqui http://www.exifviewer.org/ , ou http://regex.info/exif.cgi ou http://www.addictivetips.com/internet-tips/view-complete-exif -metadata-information-of-any-jpeg-image-online /
fonte
Tive o mesmo problema ao obter a imagem da Camera, coloquei o seguinte código para corrigi-lo .. Adicionado o método scaleAndRotateImage a partir daqui
fonte
Copie / cole rápida tradução rápida da excelente resposta de Dilip .
fonte
A resposta para isso é muito simples. A Apple NÃO está girando a imagem. É aí que reside a confusão.
A câmera CCD não gira, por isso está sempre tirando a foto no modo paisagem.
A Apple fez uma coisa muito inteligente - em vez de gastar todo o tempo girando a imagem - misturando megabytes de dados - apenas marque COMO a foto foi tirada.
OpenGL faz traduções muito facilmente - para que os DADOS nunca sejam embaralhados - apenas COMO SEUS DESENHADOS.
Daí os metadados de orientação.
Isso se torna um problema se você deseja cortar, redimensionar etc - mas uma vez que você sabe o que está acontecendo, você apenas define sua matriz e tudo funciona.
fonte
Versão do Swift 4 com verificações de segurança da resposta de Dilip .
fonte
(bounds.size.height, bounds.size.width) = (bounds.size.width, bounds.size.height)
sem criar variáveis como armazenamento.bounds.size.height.round()
bounds.size.width.round()
Qualquer imagem gerada pelo iPhone / iPad é salva como Paisagem Esquerda com a tag de Orientação EXIF (Exif.Image.Orientation) especificando a orientação real.
Tem os seguintes valores: 1: Paisagem Esquerda 6: Retrato Normal 3: Paisagem Direita 4: Retrato De cabeça para baixo
No IOS, as informações EXIF são lidas corretamente e as imagens são exibidas da mesma forma que foram tiradas. Mas no Windows, a informação EXIF NÃO é usada.
Se você abrir uma dessas imagens no GIMP, ela dirá que a imagem tem informações de rotação.
fonte
Para qualquer pessoa que use o Xamarin, aqui está uma tradução em C # de Dilip ótima resposta e um agradecimento a thattyson pela tradução do Swift .
fonte
Eu me deparei com essa pergunta porque estava tendo um problema semelhante, mas usando o Swift. Só queria fazer um link para a resposta que funcionou para mim para qualquer outro desenvolvedor Swift: https://stackoverflow.com/a/26676578/3904581
Aqui está um snippet do Swift que corrige o problema de forma eficiente:
Super simples. Uma linha de código. Problema resolvido.
fonte
Eu sei exatamente qual é o seu problema. Você está usando o UIImagePicker, o que é estranho em todos os sentidos. Eu sugiro que você use AVFoundation para a câmera, que oferece flexibilidade na orientação e também na qualidade. Use AVCaptureSession. Você pode obter o código aqui. Como salvar fotos tiradas com AVFoundation no álbum de fotos?
fonte
Refatorado rapidamente para Swift 3 (alguém pode testá-lo e confirmar se tudo está funcionando bem?):
fonte
Aqui está a versão Swift3 da resposta incrível de Dilip
fonte
Tente alterar o formato da imagem para .jpeg. Isso funcionou para mim
fonte