Attualmente sto cercando di ottenere il valore alfa di un pixel in UIImageView. Ho ottenuto CGImage da [UIImageView image] e ho creato un array di byte RGBA da questo. Alpha è premoltiplicato.Recupero di un valore alfa pixel per una 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);
Ho quindi calcolare l'indice di matrice per il canale alfa in base alle coordinate del UIImageView.
int byteIndex = (bytesPerRow * uiViewPoint.y) + uiViewPoint.x * bytesPerPixel;
unsigned char alpha = rawData[byteIndex + 3];
Tuttavia non ottengo i valori che mi aspetto. Per un'area completamente nera trasparente dell'immagine ottengo valori diversi da zero per il canale alfa. Devo tradurre le coordinate tra UIKit e Core Graphics - cioè: l'asse y è invertito? O ho frainteso i valori alfa premoltiplicati?
Aggiornamento:
suggerimento di @Nikolai Ruhe è stato fondamentale per questo. In realtà non avevo bisogno di tradurre tra coordinate UIKit e coordinate di Core Graphics. Tuttavia, dopo aver impostato il metodo di fusione miei valori alfa erano quello che mi aspettavo:
CGContextSetBlendMode(context, kCGBlendModeCopy);
Hey teabot - Mi rendo conto che questa domanda ha già una risposta, ma stavo facendo qualcosa di simile a questo qualche giorno fa. Invece di disegnare l'intera immagine e quindi indicizzarla nell'array di byte, dovresti disegnare solo 1px dell'immagine sorgente in un contesto bitmap 1px per 1pz. Puoi usare il parametro rect in CGContextDrawImage per inserire il pixel giusto, ed è come 1000 volte più veloce :-) –
Grazie per il commento @Ben Gotow - Io disegno solo l'immagine una volta e poi continuo ad usare lo stesso array di byte. @Nikolai Ruhe ha anche suggerito il disegno a pixel singolo, ma ha detto che il mio approccio con array sarebbe stato più veloce se non avessi avuto bisogno di disegnare l'immagine più di una volta, ma dovessi cercare ripetutamente l'alfa. – teabot
Solo un rapido aggiornamento (anni dopo) dopo l'utilizzo di questa e un'altra domanda qui per un problema simile: Il parametro rect su CGContextDrawImage viene utilizzato per controllare "La posizione e le dimensioni nello spazio utente del riquadro di delimitazione in cui disegnare l'immagine. " Quindi, se rendi quella dimensione 1x1, riduci l'intera immagine a 1x1 prima di disegnarla. Per ottenere il pixel giusto è necessario utilizzare CGContextTranslateCTM come nella risposta di Nikolai e lasciare la dimensione del rect uguale all'immagine sorgente per evitare il ridimensionamento. – roguenet