FYI, saya menggabungkan jawaban Keremk dengan garis besar asli saya, membersihkan kesalahan ketik, menggeneralisasikannya untuk mengembalikan serangkaian warna dan mengumpulkan semuanya untuk dikompilasi. Inilah hasilnya:
+ (NSArray*)getRGBAsFromImage:(UIImage*)image atX:(int)x andY:(int)y count:(int)count
{
NSMutableArray *result = [NSMutableArray arrayWithCapacity:count];
// First get the image into your data buffer
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
// Now your rawData contains the image data in the RGBA8888 pixel format.
NSUInteger byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
for (int i = 0 ; i < count ; ++i)
{
CGFloat alpha = ((CGFloat) rawData[byteIndex + 3] ) / 255.0f;
CGFloat red = ((CGFloat) rawData[byteIndex] ) / alpha;
CGFloat green = ((CGFloat) rawData[byteIndex + 1] ) / alpha;
CGFloat blue = ((CGFloat) rawData[byteIndex + 2] ) / alpha;
byteIndex += bytesPerPixel;
UIColor *acolor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
[result addObject:acolor];
}
free(rawData);
return result;
}
getRGBAsFromImage:image atX:0 andY:0 count:image.size.width*image.size.height
Untuk mendapatkan RGBA untuk baris terakhir gambar:getRGBAsFromImage:image atX:0 andY:image.size.height-1 count:image.size.width
Salah satu cara melakukannya adalah dengan menggambar gambar ke konteks bitmap yang didukung oleh buffer yang diberikan untuk ruang warna yang diberikan (dalam hal ini adalah RGB): (perhatikan bahwa ini akan menyalin data gambar ke buffer itu, jadi Anda lakukan ingin menyimpannya alih-alih melakukan operasi ini setiap kali Anda perlu mendapatkan nilai piksel)
Lihat di bawah sebagai sampel:
sumber
CGContextDrawImage
membutuhkan tiga argumen dan di atas hanya dua yang diberikan ... Saya pikir seharusnyaCGContextDrawImage(context, CGRectMake(0, 0, width, height), image)
Tanya Jawab Teknis Apple QA1509 menunjukkan pendekatan sederhana berikut:
Gunakan
CFDataGetBytePtr
untuk sampai ke byte aktual (dan berbagaiCGImageGet*
metode untuk memahami bagaimana menafsirkannya).sumber
Tidak percaya bahwa tidak ada satu jawaban yang benar di sini. Tidak perlu mengalokasikan pointer, dan nilai-nilai unmultiplied masih perlu dinormalisasi. Untuk memotong ke pengejaran, berikut adalah versi yang benar untuk Swift 4. Untuk
UIImage
digunakan saja.cgImage
.Alasan Anda harus menggambar / mengubah gambar terlebih dahulu menjadi buffer adalah karena gambar dapat memiliki beberapa format berbeda. Langkah ini diperlukan untuk mengubahnya menjadi format yang konsisten yang dapat Anda baca.
sumber
let imageObj = UIImage(named:"greencolorImg.png"); imageObj.cgImage?.colors(at: [pt1, pt2])
pt1
danpt2
adalahCGPoint
variabel.Berikut adalah utas SO di mana @Matt hanya merender piksel yang diinginkan ke dalam konteks 1x1 dengan menggeser gambar sehingga piksel yang diinginkan sejajar dengan satu piksel dalam konteks.
sumber
sumber
UIImage adalah pembungkus byte yang merupakan CGImage atau CIImage
Menurut Referensi Apple pada UIImage objek tidak dapat diubah dan Anda tidak memiliki akses ke backing byte. Meskipun benar bahwa Anda dapat mengakses data CGImage jika Anda mengisi
UIImage
denganCGImage
(secara eksplisit atau implisit), itu akan kembaliNULL
jikaUIImage
didukung oleh aCIImage
dan sebaliknya.Trik umum untuk mengatasi masalah ini
Seperti yang disebutkan pilihan Anda
Tak satu pun dari ini adalah trik yang sangat baik jika Anda ingin output yang bukan data ARGB, PNG, atau JPEG dan data belum didukung oleh CIImage.
Rekomendasi saya, coba CIImage
Saat mengembangkan proyek Anda, mungkin lebih masuk akal bagi Anda untuk menghindari UIImage sama sekali dan memilih sesuatu yang lain. UIImage, sebagai pembungkus gambar Obj-C, sering didukung oleh CGImage ke titik di mana kami menerima begitu saja. CIImage cenderung menjadi format pembungkus yang lebih baik karena Anda dapat menggunakan konteks CIC untuk mengeluarkan format yang Anda inginkan tanpa perlu tahu bagaimana itu dibuat. Dalam kasus Anda, mendapatkan bitmap adalah masalah menelepon
- render: toBitmap: rowBytes: bounds: format: colorSpace:
Sebagai bonus tambahan, Anda dapat mulai melakukan manipulasi gambar dengan merantai filter ke gambar. Ini memecahkan banyak masalah di mana gambar terbalik atau perlu diputar / diskalakan dll.
sumber
Berdasarkan jawaban Olie dan Algal, berikut adalah jawaban terbaru untuk Swift 3
cepat
sumber
Versi Swift 5
Jawaban yang diberikan di sini sudah kedaluwarsa atau salah karena mereka tidak memperhitungkan yang berikut ini:
image.size.width
/image.size.height
.UIView.drawHierarchy(in:afterScreenUpdates:)
metode dapat menghasilkan gambar BGRA.CGImage
, ukuran baris piksel dalam byte bisa lebih besar dari sekadar perkalian lebar piksel dengan 4.Kode di bawah ini adalah untuk menyediakan solusi Swift 5 universal untuk mendapatkan
UIColor
pixel untuk semua kasus khusus tersebut. Kode dioptimalkan untuk kegunaan dan kejelasan, bukan untuk kinerja.sumber
componentLayout
juga kehilangan kasing ketika hanya ada alpha.alphaOnly
,.UIImage
, yang akan Anda lakukan sebelum mulai membaca warna pikselnya.Berdasarkan jawaban yang berbeda tetapi terutama pada ini , ini bekerja untuk apa yang saya butuhkan:
Sebagai hasil dari baris ini, Anda akan memiliki pixel dalam format AARRGGBB dengan alpha selalu diatur ke FF dalam integer unsigned 4 byte
pixel1
.sumber
Untuk mengakses nilai RGB mentah dari UIImage di Swift 5 gunakan CGImage yang mendasarinya dan dataProvider-nya:
https://www.ralfebert.de/ios/examples/image-processing/uiimage-raw-pixels/
sumber