Adakah yang tahu mengapa CGContextDrawImage
gambar saya terbalik? Saya memuat gambar dari aplikasi saya:
UIImage *image = [UIImage imageNamed:@"testImage.png"];
Dan kemudian hanya meminta grafis inti untuk menariknya ke konteks saya:
CGContextDrawImage(context, CGRectMake(0, 0, 145, 15), image.CGImage);
Itu membuat di tempat yang tepat, dan dimensi, tetapi gambar terbalik. Saya harus kehilangan sesuatu yang sangat jelas di sini?
ios
cocoa-touch
core-graphics
cgcontextdrawimage
rustyshelf
sumber
sumber
Bahkan setelah menerapkan semua yang saya sebutkan, saya masih punya drama dengan gambar. Pada akhirnya, saya baru saja menggunakan Gimp untuk membuat versi 'flipped vertical' dari semua gambar saya. Sekarang saya tidak perlu menggunakan Transforms. Semoga ini tidak akan menyebabkan masalah lebih lanjut di trek.
Quartz2d menggunakan sistem koordinat yang berbeda, di mana asalnya berada di sudut kiri bawah. Jadi, ketika Kuarsa menarik piksel x [5], y [10] dari gambar 100 * 100, piksel itu sedang digambar di sudut kiri bawah, bukan di kiri atas. Sehingga menyebabkan gambar 'terbalik'.
Sistem x koordinat cocok, jadi Anda perlu membalikkan koordinat y.
Ini berarti kami telah menerjemahkan gambar dengan 0 unit pada sumbu x dan oleh tinggi gambar pada sumbu y. Namun, ini saja akan berarti gambar kita masih terbalik, hanya ditarik "image.size.height" di bawah di mana kita ingin gambar itu diambil.
Panduan pemrograman Quartz2D merekomendasikan penggunaan ScaleCTM dan memberikan nilai negatif untuk membalik gambar. Anda dapat menggunakan kode berikut untuk melakukan ini -
Kombinasikan keduanya tepat sebelum
CGContextDrawImage
panggilan Anda dan Anda harus memiliki gambar yang digambar dengan benar.Berhati-hatilah jika koordinat imageRect Anda tidak cocok dengan gambar Anda, karena Anda bisa mendapatkan hasil yang tidak diinginkan.
Untuk mengonversi kembali koordinat:
sumber
CGContextSaveGState()
danCGContextRestoreGState()
menyimpan serta memulihkan matriks transformasi?Terbaik dari kedua dunia, gunakan UIImage
drawAtPoint:
ataudrawInRect:
saat masih menentukan konteks khusus Anda:Anda juga menghindari mengubah konteks Anda dengan
CGContextTranslateCTM
atauCGContextScaleCTM
yang jawaban kedua lakukan.sumber
UIGraphicsBeginImageContextWithOptions
alih-alih hanya mencari yang baruCGContext
, sepertinya berhasil.Dokumen Quartz2D yang relevan: https://developer.apple.com/library/ios/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html#//apple_ref/doc/uid/TP40010156-14
sumber
Jika ada yang tertarik pada solusi no-brainer untuk menggambar gambar dalam kotak kustom dalam konteks:
Gambar akan diskalakan untuk mengisi kotak.
sumber
Saya tidak yakin
UIImage
, tetapi perilaku semacam ini biasanya terjadi ketika koordinat dibalik. Sebagian besar sistem koordinat OS X berasal dari sudut kiri bawah, seperti pada Postscript dan PDF. TapiCGImage
sistem koordinat berasal dari sudut kiri atas.Solusi yang mungkin dapat melibatkan
isFlipped
properti atauscaleYBy:-1
transformasi affine.sumber
UIImage
mengandungCGImage
sebagai anggota konten utamanya serta faktor penskalaan dan orientasi. KarenaCGImage
dan berbagai fungsinya berasal dari OSX, ia mengharapkan sistem koordinat yang terbalik dibandingkan dengan iPhone. Saat Anda membuatUIImage
, standar untuk orientasi terbalik untuk kompensasi (Anda dapat mengubah ini!). Menggunakan .CGImage
properti untuk mengakses fungsi yang sangat kuatCGImage
, tetapi menggambar ke layar iPhone dll. paling baik dilakukan denganUIImage
metode.sumber
Jawaban tambahan dengan kode Swift
Grafik kuarsa 2D menggunakan sistem koordinat dengan asal di kiri bawah sedangkan UIKit di iOS menggunakan sistem koordinat dengan asal di kiri atas. Semuanya biasanya berfungsi dengan baik tetapi ketika melakukan beberapa operasi grafis, Anda harus memodifikasi sendiri sistem koordinat. The dokumentasi menyatakan:
Fenomena ini dapat dilihat dalam dua contoh tampilan kustom yang menarik gambar dalam
drawRect
metode mereka .Di sisi kiri, gambar terbalik dan di sisi kanan sistem koordinat telah diterjemahkan dan diskalakan sehingga asal berada di kiri atas.
Gambar terbalik
Sistem koordinat yang dimodifikasi
sumber
Swift 3.0 & 4.0
Tidak Perlu Mengubah
sumber
Kami dapat memecahkan masalah ini menggunakan fungsi yang sama:
sumber
drawInRect
tentu cara untuk pergi. Inilah hal kecil lain yang akan berguna saat melakukan hal ini. Biasanya gambar dan persegi panjang yang akan dituju tidak sesuai. Dalam hal inidrawInRect
akan meregangkan gambar. Berikut cara cepat dan keren untuk memastikan bahwa rasio aspek gambar tidak berubah, dengan membalik transformasi (yang akan cocok dengan semuanya):sumber
Solusi Swift 3 CoreGraphics
Jika Anda ingin menggunakan CG untuk alasan apa pun, alih-alih UIImage, konstruksi Swift 3 ini berdasarkan jawaban sebelumnya memang memecahkan masalah bagi saya:
sumber
Itu terjadi karena QuartzCore memiliki sistem koordinat "kiri bawah", sedangkan UIKit - "kiri atas".
Dalam hal ini Anda dapat memperluas CGContext :
sumber
Saya menggunakan Swift 5 ini , ekstensi Core Graphics murni yang dengan benar menangani asal bukan nol dalam rect gambar:
Anda dapat menggunakannya persis seperti metode
CGContext
biasadraw(: in:)
:sumber
Selama proyek saya, saya melompat dari jawaban Kendall ke jawaban Cliff untuk memecahkan masalah ini untuk gambar yang diambil dari telepon itu sendiri.
Pada akhirnya saya
CGImageCreateWithPNGDataProvider
malah menggunakan :Ini tidak mengalami masalah orientasi yang akan Anda dapatkan dari mendapatkan
CGImage
dariUIImage
dan itu dapat digunakan sebagai kontenCALayer
tanpa hambatan.sumber
sumber
Swift 5 menjawab berdasarkan @ ZpaceZombor
Jika Anda memiliki UIImage, gunakan saja
Jika Anda memiliki CGImage gunakan kategori saya di bawah ini
Catatan: Tidak seperti beberapa jawaban lain, jawaban ini memperhitungkan bahwa rect yang ingin Anda tarik mungkin memiliki y! = 0. Jawaban yang tidak memperhitungkannya salah dan tidak akan berfungsi dalam kasus umum.
Gunakan seperti ini:
sumber
Anda juga dapat mengatasi masalah ini dengan melakukan ini:
sumber