Alguém sabe por CGContextDrawImage
que estaria desenhando minha imagem de cabeça para baixo? Estou carregando uma imagem do meu aplicativo:
UIImage *image = [UIImage imageNamed:@"testImage.png"];
E, em seguida, basta pedir aos gráficos principais para atraí-lo para o meu contexto:
CGContextDrawImage(context, CGRectMake(0, 0, 145, 15), image.CGImage);
É renderizado no lugar certo e nas dimensões, mas a imagem está de cabeça para baixo. Eu devo estar perdendo algo realmente óbvio aqui?
ios
cocoa-touch
core-graphics
cgcontextdrawimage
enferrujado
fonte
fonte
Mesmo depois de aplicar tudo o que mencionei, ainda tive dramas com as imagens. No final, acabei de usar o Gimp para criar uma versão 'invertida vertical' de todas as minhas imagens. Agora não preciso usar nenhuma transformação. Espero que isso não cause mais problemas na pista.
O Quartz2d usa um sistema de coordenadas diferente, onde a origem está no canto inferior esquerdo. Portanto, quando o Quartz desenha o pixel x [5], y [10] de uma imagem 100 * 100, esse pixel está sendo desenhado no canto inferior esquerdo em vez de no canto superior esquerdo. Assim, causando a imagem 'invertida'.
O sistema de coordenadas x corresponde, então você precisará inverter as coordenadas y.
Isso significa que traduzimos a imagem em 0 unidades no eixo x e na altura das imagens no eixo y. No entanto, isso por si só significará que nossa imagem ainda está de cabeça para baixo, apenas sendo desenhada "image.size.height" abaixo de onde desejamos que ela seja desenhada.
O guia de programação do Quartz2D recomenda o uso do ScaleCTM e a passagem de valores negativos para inverter a imagem. Você pode usar o seguinte código para fazer isso -
Combine os dois antes da sua
CGContextDrawImage
ligação e você deverá ter a imagem desenhada corretamente.Apenas tome cuidado se as coordenadas do imageRect não corresponderem às da sua imagem, pois você pode obter resultados indesejados.
Para converter de volta as coordenadas:
fonte
CGContextSaveGState()
eCGContextRestoreGState()
para salvar e restaurar a matriz de transformação?Melhor dos dois mundos, use UIImage
drawAtPoint:
oudrawInRect:
enquanto especifica seu contexto personalizado:Além disso, evite modificar seu contexto com
CGContextTranslateCTM
ou com oCGContextScaleCTM
que a segunda resposta o faz.fonte
UIGraphicsBeginImageContextWithOptions
vez de apenas introduzir um novoCGContext
, parecia funcionar.Documentos relevantes do Quartz2D: https://developer.apple.com/library/ios/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html#//apple_ref/doc/uid/TP40010156-CH14-SW4
fonte
Se alguém estiver interessado em uma solução simples para desenhar uma imagem em um ret personalizado em um contexto:
A imagem será redimensionada para preencher o retângulo.
fonte
Não tenho certeza
UIImage
, mas esse tipo de comportamento geralmente ocorre quando as coordenadas são invertidas. A maioria dos sistemas de coordenadas do OS X tem sua origem no canto inferior esquerdo, como em Postscript e PDF. Mas oCGImage
sistema de coordenadas tem sua origem no canto superior esquerdo.As possíveis soluções podem envolver uma
isFlipped
propriedade ou umascaleYBy:-1
transformação afim.fonte
UIImage
contém umCGImage
membro de conteúdo principal e fatores de dimensionamento e orientação. ComoCGImage
e suas várias funções são derivadas do OSX, ele espera um sistema de coordenadas de cabeça para baixo em comparação com o iPhone. Quando você cria umUIImage
, o padrão é uma orientação invertida para compensar (você pode alterar isso!). Use o .CGImage
propriedade para acessarCGImage
funções muito poderosas , mas é melhor desenhar na tela do iPhone etc. com osUIImage
métodos.fonte
Resposta suplementar com código Swift
Os gráficos 2D de quartzo usam um sistema de coordenadas com a origem no canto inferior esquerdo, enquanto o UIKit no iOS usa um sistema de coordenadas com a origem no canto superior esquerdo. Geralmente, tudo funciona bem, mas ao fazer algumas operações gráficas, você deve modificar o sistema de coordenadas. A documentação declara:
Esse fenômeno pode ser visto nas duas instâncias a seguir de visualizações personalizadas que desenham uma imagem em seus
drawRect
métodos.No lado esquerdo, a imagem está de cabeça para baixo e no lado direito o sistema de coordenadas foi traduzido e dimensionado para que a origem esteja no canto superior esquerdo.
Imagem de cabeça para baixo
Sistema de coordenadas modificado
fonte
Swift 3.0 e 4.0
Nenhuma alteração necessária
fonte
Podemos resolver esse problema usando a mesma função:
fonte
drawInRect
é certamente o caminho a percorrer. Aqui está outra coisinha que será útil ao fazer isso. Normalmente, a figura e o retângulo com o qual vai se encaixar não se adaptam. Nesse casodrawInRect
, esticará a imagem. Aqui está uma maneira rápida e bacana de garantir que a proporção da imagem não seja alterada, revertendo a transformação (que será adequada para tudo):fonte
Solução Swift 3 CoreGraphics
Se você deseja usar o CG por qualquer motivo, em vez de UIImage, essa construção do Swift 3 com base nas respostas anteriores resolveu o problema para mim:
fonte
Isso acontece porque o QuartzCore possui o sistema de coordenadas "inferior esquerdo", enquanto o UIKit - "superior esquerdo".
No caso, você pode estender o CGContext :
fonte
Eu uso esta extensão pura do Swift 5 , Core Graphics, que lida corretamente com origens diferentes de zero em rects de imagem:
Você pode usá-lo exatamente como
CGContext
odraw(: in:)
método regular :fonte
Durante o curso do meu projeto, pulei da resposta de Kendall para a resposta de Cliff para resolver esse problema para imagens carregadas do próprio telefone.
No final, acabei usando
CGImageCreateWithPNGDataProvider
:Isso não sofre com os problemas de orientação que você obteria com o
CGImage
aUIImage
e pode ser usado como o conteúdo de umCALayer
sem problemas.fonte
fonte
Resposta rápida 5 baseada na excelente resposta do @ ZpaceZombor
Se você possui uma UIImage, basta usar
Se você tem uma CGImage, use minha categoria abaixo
Nota: Diferentemente de outras respostas, esta leva em consideração que o texto que você deseja extrair pode ter y! = 0. Essas respostas que não levam isso em consideração estão incorretas e não funcionam no caso geral.
Use assim:
fonte
Você também pode resolver esse problema fazendo o seguinte:
fonte