Ich versuche derzeit, den Alpha-Wert eines Pixels in einem UIImageView zu erhalten. Ich habe den CGImage von [UIImageView image] erhalten und daraus ein RGBA-Byte-Array erstellt. Alpha wird vormultipliziert.Abrufen eines Pixel Alpha-Werts für ein 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);
I für den gegebenen alpha-Kanal die Koordinaten aus dem UIImageView unter Verwendung des Array-Index dann berechnen.
int byteIndex = (bytesPerRow * uiViewPoint.y) + uiViewPoint.x * bytesPerPixel;
unsigned char alpha = rawData[byteIndex + 3];
Allerdings bekomme ich nicht die Werte, die ich erwarte. Für einen vollständig schwarzen transparenten Bereich des Bildes bekomme ich Werte ungleich null für den Alpha-Kanal. Muss ich die Koordinaten zwischen UIKit und Core Graphics übersetzen - d. H. Ist die Y-Achse invertiert? Oder habe ich vorgemerkte Alpha-Werte falsch verstanden?
Update:
@Nikolai Ruhe Vorschlag war zu diesen Schlüsseln. Ich musste nicht zwischen UIKit-Koordinaten und Core-Graphics-Koordinaten übersetzen. Doch nach dem Mischmodus meiner Alpha-Werte Einstellung waren, was ich erwartet habe:
CGContextSetBlendMode(context, kCGBlendModeCopy);
Hey Teabot - Ich weiß, dass diese Frage bereits beantwortet ist, aber ich habe etwas ähnliches vor ein paar Tagen gemacht. Anstatt das gesamte Bild zu zeichnen und dann in das Byte-Array zu indizieren, sollten Sie nur 1px des Quellbilds in einen 1px-1px-Bitmap-Kontext zeichnen. Sie können den rect-Parameter in CGContextDrawImage verwenden, um das richtige Pixel einzufügen, und es ist 1000-mal schneller :-) –
Danke für den Kommentar @Ben Gotow - Ich zeichne das Bild nur einmal und benutze dann dasselbe Byte-Array. @Nikolai Ruhe schlug auch das Zeichnen eines einzelnen Pixels vor, sagte aber, dass mein Array-Ansatz schneller wäre, wenn ich das Bild nicht mehr als einmal zeichnen müsste, sondern das Alpha wiederholt suchen müsste. – teabot
Nur ein kurzes Update (Jahre später) nach der Verwendung dieser und einer anderen Frage hier für ein ähnliches Problem: Der rect-Parameter auf CGContextDrawImage wird verwendet, um "Die Position und Abmessungen im Benutzerbereich des Begrenzungsrahmens, in dem das Bild zu zeichnen. " Also, wenn Sie das Rect 1x1 in der Größe machen, wird es das gesamte Bild auf 1x1 skalieren, bevor es gezeichnet wird. Um das richtige Pixel zu erhalten, müssen Sie CGContextTranslateCTM wie in Nikolais Antwort verwenden und die Größe des Rechtecks gleich dem Quellbild belassen, um eine Skalierung zu vermeiden. – roguenet