Ambil tangkapan layar area tertentu secara terprogram

Seperti yang Anda lihat di kode saya, saya mengambil tangkapan layar dan menyimpannya ke album foto.

//for retina displays
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
} else {
    UIGraphicsBeginImageContext(self.view.bounds.size);
}
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);

Pada awalnya saya menggunakan webview.size bukannya self.view.bounds.size dan itu berfungsi dengan baik karena tampilannya terletak di 0/0. Tapi sekarang saya memusatkan WebView tetapi gambarnya dimulai pada 0/0 untuk ukuran tertentu.

Bagaimana cara mengonfigurasi agar tangkapan layar dimulai pada location lain (mis. 300/150) untuk ukuran tertentu?

Atau ada cara lain untuk memotret UIWebView?


person Sharky    schedule 02.01.2012    source sumber
comment
Apakah ini berfungsi di desktop OSX atau hanya iPhone?   -  person Noitidart    schedule 07.05.2015


Jawaban (4)


Anda perlu melakukan dua perubahan agar hanya mengambil sebagian layar:

  1. Buat gambar yang lebih kecil - gunakan ukuran persegi yang ingin Anda ambil.
  2. Pindahkan asal konteks yang Anda render menjadi x/y negatif dari persegi yang ingin Anda tangkap.

Setelah itu, Anda tinggal merender layer ke dalam konteks seperti yang Anda lakukan, dan Anda akan mendapatkan apa yang Anda cari. Sesuatu seperti ini seharusnya berhasil:

CGRect grabRect = CGRectMake(40,40,300,200);

//for retina displays
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    UIGraphicsBeginImageContextWithOptions(grabRect.size, NO, [UIScreen mainScreen].scale);
} else {
    UIGraphicsBeginImageContext(grabRect.size);
}
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -grabRect.origin.x, -grabRect.origin.y);
[self.view.layer renderInContext:ctx];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
person escrafford    schedule 08.03.2013
comment
Ini membuat aplikasi saya mogok. Tahu kenapa? Saya telah menambahkan kerangka QuartzCore dan memasukkan kode ini ke dalam sebuah fungsi, tetapi tetap tidak dapat dilakukan. - person rebellion; 05.06.2013
comment
@rebellion - Saya berhasil. Meski tidak ada di album foto. Lihat adaptasi saya di bawah sebagai metode kategori UIView. - person idStar; 21.06.2013
comment
Terima kasih, ini sangat bermanfaat bagi saya. Cuma sedikit masalah warna background gambarnya putih, saya maunya transparan. Bagaimana saya bisa melakukan itu. Tolong bantu - person iMemon; 06.11.2013
comment
Warna latar belakang gambar adalah putih karena saya mengunggah gambar jpeg, bukan gambar png. Kode di atas sempurna :) - person iMemon; 06.11.2013

Saya telah mengambil dan menguji jawaban @escrafford di atas, dan membuatnya berfungsi dengan baik. Saya mengujinya dalam konteks menjadikannya metode kategori di UIView, sehingga 'grabRect' dapat diparamatisasi. Inilah kode itu, sebagai kategori UIView yang mengembalikan UIImageView kepada Anda:

/**
 Takes a screenshot of a UIView at a specific point and size, as denoted by
 the provided croppingRect parameter. Returns a UIImageView of this cropped
 region.

 CREDIT: This is based on @escrafford's answer at http://stackoverflow.com/a/15304222/535054
*/
- (UIImageView *)rp_screenshotImageViewWithCroppingRect:(CGRect)croppingRect {
    // For dealing with Retina displays as well as non-Retina, we need to check
    // the scale factor, if it is available. Note that we use the size of teh cropping Rect
    // passed in, and not the size of the view we are taking a screenshot of.
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
        UIGraphicsBeginImageContextWithOptions(croppingRect.size, YES, [UIScreen mainScreen].scale);
    } else {
        UIGraphicsBeginImageContext(croppingRect.size);
    }

    // Create a graphics context and translate it the view we want to crop so
    // that even in grabbing (0,0), that origin point now represents the actual
    // cropping origin desired:
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(ctx, -croppingRect.origin.x, -croppingRect.origin.y);
    [self.layer renderInContext:ctx];

    // Retrieve a UIImage from the current image context:
    UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Return the image in a UIImageView:
    return [[UIImageView alloc] initWithImage:snapshotImage];
}
person idStar    schedule 20.06.2013
comment
Kode ini tentu saja, dengan asumsi ARC dan terkini (solusi yang berfungsi) seperti pada iOS6.1. - person idStar; 21.06.2013

Saya memecahkan masalah saya tetapi tidak menjawab pertanyaan:

Saya membuat subkelas UIView dan memindahkan UIWebView saya ke sana, sehingga letaknya 0/0 relatif terhadap subkelas tersebut. Kemudian gunakan ukuran WebView:

UIGraphicsBeginImageContext(webview.frame.size);

dan kode lainnya dari atas.

Sekarang Anda dapat memindahkan subkelas ke setiap lokasi yang Anda inginkan.

Catatan: Jika Anda memiliki label seperti label tanggal/waktu, Anda harus memindahkannya juga atau Anda tidak akan melihatnya di gambar.

Jadi buatlah subkelas UIView dan pindahkan setiap IBOutlet yang ingin Anda lihat pada gambar di sana.

Pertanyaannya masih terbuka: Apakah mungkin mengambil gambar pada area tertentu di layar?

Salam Hormat. $h@rky

person Sharky    schedule 09.01.2012

- (void)drawRect:(CGRect)rect {
  UIGraphicsBeginImageContext(self.bounds.size);    
  [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);  
}

Anda dapat menyebut ini sebagai pandangan Anda :]

person Nils Munch    schedule 02.01.2012
comment
Metode drawRect dipanggil ketika tampilan web dibuat - jadi saya memiliki gambar abu-abu di awal. Ide yang saya dapatkan dari ini adalah untuk menyeret kode dan melepaskannya ke kelas UIView khusus saya tempat tampilan web saya berada pada 0/0. Itu berfungsi tetapi saya tidak melihat labelnya lagi karena itu adalah bagian dari tampilan root. - person Sharky; 03.01.2012