Meu código funciona bem para dispositivos normais, mas cria imagens borradas em dispositivos retina.
Alguém conhece uma solução para o meu problema?
+ (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContext(view.bounds.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Respostas:
Alterne do uso de
UIGraphicsBeginImageContext
paraUIGraphicsBeginImageContextWithOptions
(conforme documentado nesta página ). Passe 0,0 para a escala (o terceiro argumento) e você obterá um contexto com um fator de escala igual ao da tela.UIGraphicsBeginImageContext
usa um fator de escala fixa de 1,0, então você está obtendo exatamente a mesma imagem em um iPhone 4 que nos outros iPhones. Aposto que o iPhone 4 está aplicando um filtro quando você o escala implicitamente ou apenas seu cérebro percebe que é menos nítido do que tudo ao seu redor.Então eu acho:
E no Swift 4:
fonte
#import <QuartzCore/QuartzCore.h>
para remover orenderInContext:
aviso.UIImage
de recarregar, mas forçar a versão de alta resolução (e você provavelmente enfrentaria problemas devido à menor RAM disponível na pré-instalação). dispositivos -retina de qualquer maneira).0.0f
parâmetro for the scale, é mais aceitável usar[[UIScreen mainScreen] scale]
, também funciona.scale: The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
É explicitamente documentado, então 0.0f é mais simples e melhor na minha opinião.A resposta atualmente aceita está desatualizada, pelo menos se você estiver suportando o iOS 7.
Aqui está o que você deve usar se estiver suportando apenas o iOS7 +:
Swift 4:
De acordo com este artigo , você pode ver que o novo método iOS7
drawViewHierarchyInRect:afterScreenUpdates:
é muitas vezes mais rápido querenderInContext:
.fonte
drawViewHierarchyInRect:afterScreenUpdates:
é muito mais rápido. Acabei de executar um criador de perfil Time em Instruments. Minha geração de imagens passou de 138ms para 27ms.afterScreenUpdates:
aYES
?viewDidLoad
ouviewWillAppear:
as imagens forem pretas; Eu tive que fazer issoviewDidAppear:
. Então, eu também finalmente volteirenderInContext:
.Eu criei uma extensão Swift com base na solução @Dima:
EDIT: Swift 4 versão melhorada
Uso:
fonte
class
função que tem uma visão?static
função, mas como não há necessidade de substituir, você pode simplesmente alterá-lo para umastatic
função em vez declass
.Usando o UIGraphicsImageRenderer moderno
fonte
renderer
com o antigodrawHierarchy
..?Para melhorar as respostas de @Tommy e @Dima, use a categoria a seguir para renderizar o UIView no UIImage com fundo transparente e sem perda de qualidade. Trabalhando no iOS7. (Ou apenas reutilize esse método na implementação, substituindo a
self
referência pela sua imagem)UIView + RenderViewToImage.h
UIView + RenderViewToImage.m
fonte
@interface
e@implementation
ambos(RenderViewToImage)
e adicionando#import "UIView+RenderViewToImage.h"
ao cabeçalho noViewController.h
então é este o uso correto? por exemploUIImageView *test = [[UIImageView alloc] initWithImage:[self imageByRenderingView]]; [self addSubview:test];
?ViewController.m
era a visão Tentei tornar- (UIView *)testView { UIView *v1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)]; v1.backgroundColor = [UIColor redColor]; UIView *v2 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)]; v2.backgroundColor = [UIColor blueColor]; [v2 addSubview:v1]; return v2; }
Swift 3
A solução Swift 3 (com base na resposta de Dima ) com extensão UIView deve ser assim:
fonte
Extensão do Drop-in Swift 3.0 que suporta a nova API do iOS 10.0 e o método anterior.
Nota:
!
que poderia causar um acidente.fonte
Swift 2.0:
Usando o método de extensão:
Uso:
fonte
Implementação do Swift 3.0
fonte
Todas as respostas do Swift 3 não funcionaram para mim, por isso traduzi a resposta mais aceita:
fonte
Aqui está uma extensão Swift 4 UIView com base na resposta do @Dima.
fonte
Para o Swift 5.1, você pode usar esta extensão:
fonte
https://nshipster.com/image-resizing/
Portanto, verifique se o tamanho que você está passando
UIGraphicsImageRenderer
é de pontos, não de pixels.Se suas imagens forem maiores do que o esperado, você precisará dividir seu tamanho pelo fator de escala.
fonte
Algumas vezes, o método drawRect cria problemas, então eu tenho essas respostas mais apropriadas. Você também pode dar uma olhada nele Capture UIImage of UIView preso no método DrawRect
fonte
fonte
Neste método, basta passar um objeto de exibição e ele retornará um objeto UIImage.
fonte
Adicione isso ao método na Categoria UIView
fonte