Thursday, March 31, 2011

Custom Kamera Pengembangan Aplikasi Menggunakan Iphone SDK

Phone berisi banyak fitur berguna. Salah satunya adalah membangun-in kamera dan Kamera sistem aplikasi untuk membuat foto. Kelihatannya bagus tapi bagaimana dengan penggunaan kamera dengan aplikasi asli? iPhone SDK menyediakan kemampuan menggunakan kamera melalui UIImagePickerController kelas. Itu bagus tapi ada kelemahan kecil - Anda tidak dapat membuat layar gigih penuh "live" tampilan kamera seperti aplikasi Kamera tidak. Alih-alih bahwa Anda harus menggunakan UIImagePickerController hanya dalam mode modal - tampilkan-up modal tampilan pop ketika Anda membutuhkan foto dan menutup tampilan setelah foto dibuat. Anda harus membuka kembali pandangan ini lagi untuk yang berikutnya.

Selain itu, pandangan modal berisi panel tambahan dan kontrol yang overlay tampilan kamera. Kerugian lain adalah - Anda tidak dapat mengambil foto dalam satu sentuhan, Anda perlu menyentuh tombol Tembak untuk mengambil gambar dan preview itu, dan kemudian Anda perlu menyentuh tombol Simpan untuk mendapatkan foto untuk diproses. Mungkin itu praktek terbaik tetapi saya tidak suka itu dan saya berharap Anda berpikir dengan cara yang sama.


Bagaimana menggunakan UIImagePickerController sebagai-modal tampilan kontroler non ordinal bawah controller navigasi dengan cara yang sama seperti kita menggunakan pengendali tampilan lain? Cobalah dan Anda akan menemukan bahwa ia bekerja! Pandangan kamera bekerja dan tampak sebagaimana mestinya. Anda dapat menetapkan delegasi dan proses UIImagePickerControllerDelegate acara untuk mendapatkan dan menyimpan foto. Ok, sentuh tombol Tembak, sentuhlah tombol Simpan - bagus, Anda punya foto! Tapi hanya melihat ini - Merebut kembali dan tombol Simpan tinggal di atas tampilan kamera, dan mereka tidak bekerja sekarang ketika mereka disentuh ... Hal ini karena Anda tidak dapat mereset pandangan untuk mengambil foto lainnya setelah mengambil satu dan menyentuh tombol Simpan, melihat adalah freezing dan tombol dinonaktifkan. Tampaknya Anda perlu untuk sepenuhnya menciptakan UIImagePickerController misalnya untuk mengambil foto lainnya. Itu tidak begitu sederhana dan tidak begitu baik. Dan Anda masih perlu menggunakan panel dan tombol yang overlay tampilan kamera ...


Sekarang aku punya ide! Ketika kita menyentuh Shoot, melihat berhenti menampilkan gambar tunggal dan menyegarkan dari kamera, maka kita harus menyentuh Merebut kembali atau tombol Simpan. Bisakah kita mendapatkan citra itu dan menyimpannya tanpa menggunakan UIImagePickerControllerDelegate dan kemudian menyentuh Merebut kembali tombol pemrograman untuk me-reset melihat dan mendapatkan foto lain? Tentu kita bisa! Jika Anda menjelajahi kamera pandangan hirarki setelah menyentuh Tembak Anda akan menemukan bahwa ada pandangan tersembunyi ImageView tipe. Kelas ini tidak dijelaskan dalam SDK, tetapi kita dapat menjelajahi 'metode-C dengan menggunakan kemampuan Tujuan. Kita bisa melihat bahwa kelas berisi metode imageRef disebut. Mari kita coba ini ... Ya, ia mengembalikan CGImage objek! Dan ukuran gambar 1200 1600 x - itu pasti gambar kamera!


Ok, sekarang kita tahu bahwa kita bisa mendapatkan foto tanpa UIImagePickerControllerDelegate . Namun dalam apa yang harus kita lakukan saat ini? Bisakah kita menangkap menyentuh pengguna pada tombol Tembak untuk mulai memproses? Itu mungkin tapi tidak begitu bagus. Apakah Anda ingat tujuan utama kita - membuat tampilan layar penuh kamera gigih seperti sistem aplikasi Kamera tidak? Saatnya untuk melakukannya! Ketika kita menjelajahi hirarki pandangan, kami telah menemukan bahwa ada sejumlah pandangan di atas tampilan kamera. Kita dapat mencoba untuk menyembunyikan pandangan dan membuat tombol kita sendiri di bawah tampilan kamera untuk mengambil foto dalam satu sentuhan. Tapi bagaimana kita bisa memaksa tampilan kamera untuk membuat foto? Ini sangat sederhana - kita bisa mendapatkan pemilih yang sesuai dari tombol Tembak dan menyebutnya dari action handler kita!


Ok, kita telah memaksa mendapatkan gambar. Tapi itu membawa kita beberapa detik. Bagaimana kita bisa mendeteksi bahwa gambar sudah siap? Ini terjadi ketika Batal dan tombol Tembak diganti dengan yang Merebut kembali dan Simpan. Cara paling mudah untuk mendeteksi ini adalah memulai timer dengan interval pendek dan memeriksa tombol. Dan kemudian kita bisa mendapatkan dan menyimpan foto, menggunakan pemilih yang sesuai dari tombol Merebut kembali dan menyebutnya untuk mengatur ulang tampilan kamera, dan siapkan untuk membuat yang baru. Berikut adalah kode:


/ / Tombol Shot pada toolbar tersentuh. Membuat foto.
- (Void) shotAction: (id) {pengirim
[Diri enableInterface: NO];
/ / Simulasikan menyentuh pada tombol Shot di Picker Image's
UIControl * camBtn = [getCamShutButton diri];
[CamBtn sendActionsForControlEvents: UIControlEventTouchUpInside];

/ / Timer Set up untuk memeriksa kamera kontrol untuk mendeteksi ketika gambar
/ / Dari kamera akan disiapkan.
/ / Gambar Picker's Shot tombol dioper sebagai userInfo untuk membandingkan dengan tombol saat ini.
[NSTimer scheduledTimerWithTimeInterval: 0.2 target: pemilih diri: @ pemilih (savePhotoTimerFireMethod:) userInfo: camBtn mengulangi: NO];
}

/ / Kembali Gambar Picker's Shoot tombol (tombol yang membuat foto).
- (UIControl *) getCamShutButton {

UIView * topView = [findCamControlsLayerView diri: self.view];
UIView * buttonsBar = [topView.subviews objectAtIndex: 2];
UIControl * btn = [buttonsBar.subviews objectAtIndex: 1];

kembali btn;
}

/ / Kembali Gambar Picker's Merebut kembali tombol yang muncul setelah pengguna menekan Tembak.
- (UIControl *) getCamRetakeButton {

UIView * topView = [findCamControlsLayerView diri: self.view];
UIView * buttonsBar = [topView.subviews objectAtIndex: 2];
UIControl * btn = [buttonsBar.subviews objectAtIndex: 0];

kembali btn;
}

/ / Cari tampilan yang berisi kontrol kamera (tombol)
- (UIView *) findCamControlsLayerView: (UIView *) melihat {

Class cl = [view kelas];
NSString * desc = [deskripsi cl];
jika ([desc bandingkan: @ "PLCropOverlay"] == NSOrderedSame)
melihat kembali;

untuk (NSUInteger i = 0; i <[view.subviews count]; i + +) { UIView * subView = [view.subviews objectAtIndex: i]; subView [findCamControlsLayerView diri: subView] =; if (subView) kembali subView; } kembali nihil; } / / Dipanggil oleh timer. Periksa kamera kontrol untuk mendeteksi bahwa gambar sudah siap. - (Void) savePhotoTimerFireMethod: (NSTimer *) theTimer { / / Bandingkan saat Gambar Picker's tombol Shot dengan berlalu. UIControl * camBtn = [getCamShutButton diri]; if (camBtn! = [theTimer userInfo]) { / / Tombol digantikan oleh tombol Simpan - gambar siap. [SaveImageFromImageView diri]; / / Sentuhan Simulasikan pada Merebut kembali tombol untuk terus bekerja, kamera siap untuk mengambil foto baru. camBtn = [getCamRetakeButton diri]; [CamBtn sendActionsForControlEvents: UIControlEventTouchUpInside]; [Diri enableInterface: YES]; } lain { NSTimeInterval interval = [theTimer timeInterval]; [NSTimer scheduledTimerWithTimeInterval: target interval: pemilih diri: @ pemilih (savePhotoTimerFireMethod:) userInfo: camBtn mengulangi: NO]; } } / / Simpan gambar yang diambil dari melihat gambar tersembunyi. - (Bool) {saveImageFromImageView UIView * cameraView = [self.view.subviews objectAtIndex: 0]; jika ([diri enumSubviewsToFindImageViewAndSavePhoto: cameraView]) kembali YES; NO kembali; } / / Subview menghitung Rekursif untuk menemukan melihat gambar tersembunyi dan menyimpan foto - (Bool) enumSubviewsToFindImageViewAndSavePhoto: (UIView *) melihat { Class cl = [view kelas]; NSString * desc = [deskripsi cl]; jika ([desc bandingkan: @ "ImageView"] == NSOrderedSame) kembali [grabPictureFromImageView diri: melihat]; for (int i = 0; i [view.subviews count] <; i + +) { jika ([diri enumSubviewsToFindImageViewAndSavePhoto: [view.subviews objectAtIndex: i]]) kembali YES; } NO kembali; } / / Ambil gambar dari melihat foto tersembunyi dan menyimpan foto - (Bool) grabPictureFromImageView: (UIView *) melihat { CGImageRef img = (CGImageRef) [view imageRef]; if (img) { / / Gambar yang diambil dalam UIImageOrientationRight orientasi UIImage * foto = [correctImageOrientation diri: img]; UIImageWriteToSavedPhotosAlbum (foto, nihil, nihil, nihil); kembali YES; } NO kembali; } / / Orientasi gambar yang benar dari UIImageOrientationRight (berputar pada 90 derajat) - (UIImage *) correctImageOrientation: (CGImageRef) {gambar CGFloat width = CGImageGetWidth (image); CGFloat height = CGImageGetHeight (image); CGRect batas = CGRectMake (0.0f, 0.0f, lebar, tinggi); CGFloat boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; CGAffineTransform mengubah CGAffineTransformMakeTranslation = (tinggi, 0.0f); mengubah = CGAffineTransformRotate (mengubah, M_PI / 2.0f); UIGraphicsBeginImageContext (bounds.size); CGContextRef context = UIGraphicsGetCurrentContext (); CGContextScaleCTM (konteks, - 1.0f, 1.0f); CGContextTranslateCTM (konteks,-height, 0.0f); CGContextConcatCTM (konteks, transformasi); CGContextDrawImage (konteks, CGRectMake (0.0f, 0.0f, lebar, tinggi), gambar); UIImage * imageCopy = UIGraphicsGetImageFromCurrentImageContext (); UIGraphicsEndImageContext (); kembali imageCopy; } Pertanyaan lain yang penting adalah: di saat apa yang bisa kita menyembunyikan pandangan kamera overlay dan kontrol dan membuat tombol kita sendiri? Mencoba viewDidLoad ... Ups ... Pandangan kamera masih belum dibuat. Mencoba viewWillAppear ... Hal yang sama ... Mencoba viewDidAppear ... Ya, pandangan telah diciptakan dan dapat disembunyikan sekarang. Ok, kita menyembunyikan itu dan membuat toolbar dengan tombol Shoot kami. Ia bekerja, tetapi film layar - kita melihat bagaimana pandangan standar dan tombol yang ditampilkan dan kemudian tersembunyi. Bagaimana kita bisa mencegah hal ini? Aku mencoba beberapa cara dan telah menemukan yang terbaik: kita harus menyembunyikan pandangan sebelum mereka ditambahkan ke tampilan kamera (bila addSubview metode tampilan kamera disebut). Itu mungkin menggunakan kemampuan Tujuan-C untuk menggantikan metode yang dinamis pada saat run-time. Ok, mari kita menggantikan addSubview dengan metode kita sendiri. Dalam metode kami dapat memeriksa bahwa pandangan melewati adalah salah satu tampilan subview kamera dan set tersembunyi "perusahaan" properti untuk YES. Jadi, kita ganti addSubview di viewWillAppear sebelum tampilan kamera dibuat. Dan kita membuat toolbar kita dan tombol Tembak di viewDidAppear setelah tampilan kamera dibuat. Lihatlah kode di bawah ini: / / Ganti "addSubview:" jika pertama kali disebut; menyembunyikan kontrol kamera sebaliknya. - (Void) viewWillAppear: (bool) {animasi [Super viewWillAppear: animasi]; if (toolbar! = nihil) { / / Pemandangan itu sudah muncul, kita tidak perlu subclass UIView / / Tapi perlu menyembunyikan kontrol kamera tambahan. UIView * cameraView = [findCamControlsLayerView diri: self.view]; if (cameraView) { cameraView = cameraView.superview; int cnt = [cameraView.subviews count]; if (> cnt = 4)
{
for (int i = 2; i {
UIView * v = [cameraView.subviews objectAtIndex: i];
v.hidden = YES;
}
}
}
}
lain
{
/ / Subclass UIView dan ganti addSubview untuk menyembunyikan kontrol kamera melihat dengan cepat.
[RootViewController exchangeAddSubViewFor: self.view];
}
}

/ / Exchange addSubview: kelas UIView; mengatur myAddSubview kita sendiri bukan
+ (Void) exchangeAddSubViewFor: (UIView *) melihat {

SEL addSubviewSel = @ pemilih (addSubview:);
Metode originalAddSubviewMethod = class_getInstanceMethod ([tampilan kelas], addSubviewSel);

SEL myAddSubviewSel = @ pemilih (myAddSubview:);
Metode replacedAddSubviewMethod = class_getInstanceMethod ([kelas diri], myAddSubviewSel);

method_exchangeImplementations (originalAddSubviewMethod, replacedAddSubviewMethod);
}

/ / Tambahkan subview untuk melihat; "diri" menunjuk ke tampilan induk.
/ / Set "tersembunyi" untuk YA jika subview adalah kamera kontrol tampilan.
- (Void) myAddSubview: (UIView *) melihat {

UIView * induk = (UIView *) diri;

Bool dilakukan = NO;
Class cl = [view kelas];
NSString * desc = [deskripsi cl];

jika ([desc bandingkan: @ "PLCropOverlay"] == NSOrderedSame)
{
untuk (NSUInteger i = 0; i <[view.subviews count]; i + +)
{
UIView * v = [view.subviews objectAtIndex: i];
v.hidden = YES;
}

dilakukan = YES;
}

[RootViewController exchangeAddSubViewFor: orang tua];

[Induk addSubview: view];

if (! dilakukan)
[RootViewController exchangeAddSubViewFor: orang tua];
}


Teknik yang dijelaskan di atas digunakan dalam aplikasi iUniqable tersedia dari Apple App Store (Social Networking bagian). Jangan ragu untuk menggunakan.


Jangan ragu untuk mengunjungi website dari pengembang www.enterra-inc.com

No comments:

Post a Comment