Tôi hiện đang cố gắng lấy giá trị alpha của pixel trong UIImageView. Tôi đã thu được CGImage từ [hình ảnh UIImageView] và tạo ra một mảng byte RGBA từ này. Alpha là thủ phạm.Lấy giá trị alpha pixel cho UIImage
CGImageRef image = uiImage.CGImage;
NSUInteger width = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
rawData = malloc(height * width * 4);
bytesPerPixel = 4;
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), image);
CGContextRelease(context);
Sau đó tôi tính toán chỉ mục mảng cho kênh alpha đã cho bằng cách sử dụng toạ độ từ UIImageView.
int byteIndex = (bytesPerRow * uiViewPoint.y) + uiViewPoint.x * bytesPerPixel;
unsigned char alpha = rawData[byteIndex + 3];
Tuy nhiên, tôi không nhận được các giá trị mà tôi mong đợi. Đối với một khu vực trong suốt hoàn toàn màu đen của hình ảnh tôi nhận được các giá trị khác 0 cho kênh alpha. Tôi có cần dịch các tọa độ giữa UIKit và Đồ họa cốt lõi - tức là: trục y đảo ngược không? Hay tôi đã hiểu lầm các giá trị alpha được ghi nhận trước?
Cập nhật:
gợi ý @Nikolai Ruhe là chìa khóa để này. Tôi không thực sự cần phải dịch giữa các tọa độ UIKit và tọa độ Đồ họa cốt lõi. Tuy nhiên, sau khi đặt chế độ hòa trộn, các giá trị alpha của tôi là những gì tôi mong đợi:
CGContextSetBlendMode(context, kCGBlendModeCopy);
Hey teabot - Tôi nhận ra câu hỏi này đã được trả lời, nhưng tôi đã làm một cái gì đó tương tự như thế này một vài ngày trước. Thay vì vẽ toàn bộ hình ảnh và sau đó lập chỉ mục vào mảng byte, bạn nên _only vẽ 1px của hình ảnh nguồn thành ngữ cảnh bitmap 1px x 1px. Bạn có thể sử dụng tham số rect trong CGContextDrawImage để đặt đúng pixel vào, và nó nhanh hơn 1000 lần :-) –
Cảm ơn nhận xét @Ben Gotow - Tôi chỉ vẽ hình ảnh một lần và sau đó tiếp tục sử dụng cùng một mảng byte. @Nikolai Ruhe cũng đề nghị vẽ điểm ảnh đơn lẻ nhưng cho rằng cách tiếp cận mảng của tôi sẽ nhanh hơn nếu tôi không cần vẽ hình ảnh nhiều lần, nhưng cần phải tra cứu alpha liên tục. – teabot
Chỉ cần cập nhật nhanh (năm sau) sau khi sử dụng câu hỏi này và một câu hỏi khác trên đây cho một vấn đề tương tự: Tham số rect trên CGContextDrawImage được sử dụng để điều khiển "Vị trí và kích thước trong không gian người dùng của hộp giới hạn để vẽ hình ảnh. " Vì vậy, nếu bạn thực hiện kích thước 1x1 trực tiếp đó, nó sẽ phóng to toàn bộ hình ảnh xuống 1x1 trước khi vẽ. Để có được pixel đúng, bạn cần sử dụng CGContextTranslateCTM như trong câu trả lời của Nikolai, và để kích thước của rect bằng với hình ảnh nguồn để ngăn chặn sự co giãn. – roguenet