Eu tenho um código que redimensiona uma imagem para que eu possa obter uma parte do centro da imagem em escala - eu uso isso para tirar UIImage
e retornar uma representação quadrada pequena de uma imagem, semelhante ao que é visto na exibição do álbum de uma imagem. o aplicativo Fotos. (Eu sei que poderia usar UIImageView
ae ajustar o modo de corte para obter os mesmos resultados, mas essas imagens às vezes são exibidas em UIWebViews
).
Comecei a perceber algumas falhas neste código e estou um pouco perplexo. Eu tenho duas teorias diferentes e estou me perguntando se alguma delas está na base.
Teoria 1) Eu obtenho o corte desenhando em um contexto de imagem fora da tela do meu tamanho-alvo. Como quero a parte central da imagem, defino o CGRect
argumento passado drawInRect
para algo maior que os limites do contexto da minha imagem. Eu esperava que isso fosse Kosher, mas estou tentando atrair outras memórias que não deveria estar tocando?
Teoria 2) Estou fazendo tudo isso em um thread de segundo plano. Eu sei que existem partes do UIKit restritas ao segmento principal. Eu estava assumindo / esperando que desenhar para uma visualização fora da tela não fosse um deles. Estou errado?
(Oh, como eu sinto falta do NSImage's drawInRect:fromRect:operation:fraction:
método.)
Respostas:
Atualização 28-05-2014: escrevi isso quando o iOS 3 era a novidade, estou certo de que existem maneiras melhores de fazer isso agora, possivelmente embutidas. Como muitas pessoas mencionaram, esse método não leva em consideração a rotação; leia algumas respostas adicionais e espalhe um pouco de amor positivo para manter as respostas a essa pergunta úteis para todos.
Resposta original:
Vou copiar / colar minha resposta para a mesma pergunta em outro lugar:
Não existe um método simples de classe para fazer isso, mas existe uma função que você pode usar para obter os resultados desejados:
CGImageCreateWithImageInRect(CGImageRef, CGRect)
irá ajudá-lo.Aqui está um pequeno exemplo de como usá-lo:
fonte
imageOrientation
está definido para qualquer coisa, exceto para cima, o valorCGImage
é girado em relação aoUIImage
retângulo de recorte e o erro fica errado. Você pode girar o retângulo de corte de acordo, mas o recém-criadoUIImage
seráimageOrientation
exibido, para que o corteCGImage
seja girado dentro dele.[UIImage imageWithCGImage:imageRef scale:largeImage.scale orientation:largeImage.imageOrientation];
Para cortar imagens da retina, mantendo a mesma escala e orientação, use o seguinte método em uma categoria UIImage (iOS 4.0 e posterior):
fonte
self.scale
, não?CGImageRelease(imageRef);
com o ARC ativado?Você pode criar uma categoria UIImage e usá-la sempre que precisar. Baseado na resposta e nos comentários do HitScans abaixo.
Você pode usá-lo desta maneira:
fonte
[[UIScreen mainScreen] scale]
ser apenasself.scale
? A escala da imagem pode não ser igual à escala da tela.No visible @interface for 'UIImage' declares the selector 'crop'
mesmo que eu coloque os arquivos de categoria .h e .m no meu projeto e importei o .h na classe que estou usando a categoria. Qualquer ideia?Versão Swift 3
com a ajuda desta função de ponte
CGRectMake
->CGRect
(créditos para esta resposta respondida por@rob mayoff
):O uso é:
Resultado:
fonte
guard
da primeira linha no caso deUIImage.CGImage
retornosnil
e por que usarvar
quandolet
funciona perfeitamente.cropping(to:)
muito cuidado. O resultadoCGImage
mantém uma forte referência ao maiorCGImage
do qual foi cortado. Portanto, se você quiser se apegar apenas à imagem cortada e não precisar do original, dê uma olhada nas outras soluções.right
, em seguida, o CGImage deve ser ccw uma rotação de 90 graus, por conseguinte, a rect colheita deve ser rodada demaisAqui está minha implementação de corte UIImage que obedece à propriedade imageOrientation. Todas as orientações foram exaustivamente testadas.
fonte
implicit declaration of function 'rad' is invalid in c99
pode ser removido por substituição: rad (90), rad (-90), rad (-180) -> M_PI_2, -M_PI_2, -_M_PIcontains undefined reference for architecture armv7
Estou faltando uma biblioteca? CoreGraphics é importado.CGImage
Atenção : todas essas respostas assumem um objeto de imagem com backup.image.CGImage
pode retornar nulo, seUIImage
for apoiado por aCIImage
, o que seria o caso se você criasse esta imagem usando aCIFilter
.Nesse caso, talvez você precise desenhar a imagem em um novo contexto e retornar a imagem ( lenta ).
fonte
Nenhuma das respostas aqui lida com todos os problemas de escala e rotação 100% corretamente. Aqui está uma síntese de tudo o que foi dito até agora, atualizado a partir do iOS7 / 8. Ele deve ser incluído como método em uma categoria no UIImage.
fonte
Versão rápida da
awolf
resposta de, que funcionou para mim:fonte
A maioria das respostas que eu vi trata apenas de uma posição de (0, 0) para (x, y). Ok, esse é um caso, mas eu gostaria que minha operação de corte estivesse centralizada. O que demorei um pouco para descobrir é a linha que segue o comentário da WTF.
Vamos considerar o caso de uma imagem capturada com uma orientação retrato:
Espero que faça sentido! Caso contrário, tente valores diferentes. Você verá que a lógica é invertida quando se trata de escolher x, y, largura e altura corretas para o seu cropRect.
fonte
swift3
fonte
Extensão rápida
fonte
Melhor solução para cortar uma UIImage no Swift , em termos de precisão, escala de pixels ...:
Instruções usadas para chamar esta função:
Nota: a inspiração inicial do código fonte escrita em Objective-C foi encontrada no blog "Cocoanetics".
fonte
Abaixo o snippet de código pode ajudar.
fonte
Parece um pouco estranho, mas funciona muito bem e leva em consideração a orientação da imagem:
fonte
Swift 5:
fonte
fonte
fonte
No iOS9.2SDK, uso o método abaixo para converter quadros de UIView em UIImage
fonte
Atualização Swift 2.0 (
CIImage
compatibilidade)Expansão da resposta de Maxim, mas funciona se sua imagem também for
CIImage
baseada.fonte
Aqui está uma versão atualizada do Swift 3 com base na resposta Noodles
fonte
Siga a resposta de @Arne. Eu apenas corrigindo a função Categoria. coloque-o na categoria UIImage.
fonte
Não fiquei satisfeito com outras soluções, porque elas demoram várias vezes (usando mais energia do que o necessário) ou têm problemas de orientação. Aqui está o que eu usei para um quadrado croppedImage em escala de uma imagem UIImage *.
fonte
Eu uso o método abaixo.
}
fonte
Veja https://github.com/vvbogdan/BVCropPhoto
fonte