Kode saya berfungsi dengan baik untuk perangkat normal tetapi membuat gambar buram pada perangkat retina.
Adakah yang tahu solusi untuk masalah saya?
+ (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContext(view.bounds.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Jawaban:
Beralih dari penggunaan
UIGraphicsBeginImageContext
keUIGraphicsBeginImageContextWithOptions
(seperti yang didokumentasikan pada halaman ini ). Lewati 0,0 untuk skala (argumen ketiga) dan Anda akan mendapatkan konteks dengan faktor skala yang sama dengan layar.UIGraphicsBeginImageContext
menggunakan faktor skala tetap 1,0, jadi Anda benar-benar mendapatkan gambar yang persis sama pada iPhone 4 seperti pada iPhone lainnya. Saya berani bertaruh iPhone 4 akan menerapkan filter ketika Anda secara implisit meningkatkannya atau otak Anda mengambilnya menjadi kurang tajam daripada segala sesuatu di sekitarnya.Jadi saya kira:
Dan di Swift 4:
sumber
#import <QuartzCore/QuartzCore.h>
untuk menghapusrenderInContext:
peringatan.UIImage
untuk memuat ulang tetapi memaksakan versi resolusi tinggi (dan Anda mungkin akan menghadapi masalah karena RAM yang lebih sedikit tersedia di pra perangkat -retina pula).0.0f
parameter for for scale, apakah lebih dapat diterima untuk digunakan[[UIScreen mainScreen] scale]
, tetapi juga berfungsi.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.
Secara eksplisit didokumentasikan, jadi 0.0f lebih sederhana dan lebih baik menurut saya.Jawaban yang saat ini diterima sudah kedaluwarsa, setidaknya jika Anda mendukung iOS 7.
Inilah yang harus Anda gunakan jika Anda hanya mendukung iOS7 +:
Swift 4:
Sesuai artikel ini , Anda dapat melihat bahwa metode iOS7 baru
drawViewHierarchyInRect:afterScreenUpdates:
jauh lebih cepat daripadarenderInContext:
.sumber
drawViewHierarchyInRect:afterScreenUpdates:
jauh lebih cepat. Saya baru saja menjalankan profiler waktu di Instrumen. Generasi gambar saya beralih dari 138ms ke 27ms.afterScreenUpdates:
keYES
?viewDidLoad
atauviewWillAppear:
gambarnya hitam; Saya harus melakukannyaviewDidAppear:
. Jadi saya juga akhirnya kembali kerenderInContext:
.Saya telah membuat ekstensi Swift berdasarkan solusi @Dima:
EDIT: Swift 4 versi yang disempurnakan
Pemakaian:
sumber
class
fungsi yang mengambil tampilan?static
fungsi tetapi karena tidak perlu untuk meng-override Anda hanya dapat mengubahnya kestatic
func sebagai gantinyaclass
.Menggunakan UIGraphicsImageRenderer modern
sumber
renderer
dengan yang lamadrawHierarchy
..?Untuk meningkatkan jawaban oleh @Tommy dan @Dima, gunakan kategori berikut untuk merender UIView ke dalam UIImage dengan latar belakang transparan dan tanpa kehilangan kualitas. Bekerja di iOS7. (Atau gunakan kembali metode itu dalam implementasi, ganti
self
referensi dengan gambar Anda)UIView + RenderViewToImage.h
UIView + RenderViewToImage.m
sumber
@interface
dan@implementation
keduanya(RenderViewToImage)
serta menambahkan#import "UIView+RenderViewToImage.h"
ke headerViewController.h
sehingga apakah ini penggunaan yang benar? misalnyaUIImageView *test = [[UIImageView alloc] initWithImage:[self imageByRenderingView]]; [self addSubview:test];
?ViewController.m
adalah pandangan yang saya coba render- (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; }
Cepat 3
Solusi Swift 3 (berdasarkan jawaban Dima ) dengan ekstensi UIView harus seperti ini:
sumber
Ekstensi Drop-in Swift 3.0 yang mendukung iOS 10.0 API baru & metode sebelumnya.
catatan:
!
yang dapat menyebabkan crash.sumber
Swift 2.0:
Menggunakan metode ekstensi:
Pemakaian:
sumber
Implementasi Swift 3.0
sumber
Semua jawaban Swift 3 tidak berhasil untuk saya, jadi saya telah menerjemahkan jawaban yang paling diterima:
sumber
Berikut adalah ekstensi Swift 4 UIView berdasarkan jawaban dari @Dima.
sumber
Untuk Swift 5.1 Anda dapat menggunakan ekstensi ini:
sumber
https://nshipster.com/image-resizing/
Jadi pastikan ukuran yang Anda lewati
UIGraphicsImageRenderer
adalah titik, bukan piksel.Jika gambar Anda lebih besar dari yang Anda harapkan, Anda perlu membagi ukuran Anda dengan faktor skala.
sumber
Beberapa kali drawRect Method membuat masalah jadi saya mendapat jawaban ini lebih tepat. Anda juga mungkin telah melihatnya Capture UIImage of UIView terjebak dalam metode DrawRect
sumber
sumber
Dalam metode ini hanya melewatkan objek tampilan dan itu akan mengembalikan objek UIImage.
sumber
Tambahkan ini ke metode ke Kategori UIView
sumber