Frage

Ich versuche ARGB Komponenten aus CGBitmapContext mit folgenden Codes zu bekommen:


-(id) initWithImage: (UIImage*) image   //create BitmapContext with UIImage and use 'pixelData' as the pointer
{

        CGContextRef    context = NULL;
        CGColorSpaceRef colorSpace;
        int             bitmapByteCount;
        int             bitmapBytesPerRow;

        bitmapBytesPerRow   = (image.size.width * 4);                       
        bitmapByteCount     = (bitmapBytesPerRow * image.size.height);

        colorSpace = CGColorSpaceCreateDeviceRGB();                         
        pixelData = malloc( bitmapByteCount );      //unsigned char* pixelData is defined in head file
        context = CGBitmapContextCreate (pixelData,                         
                        image.size.width,
                        image.size.height,
                        8,    // bits per component
                        bitmapBytesPerRow,
                        colorSpace,
                        kCGImageAlphaPremultipliedFirst
                        );
        CGColorSpaceRelease( colorSpace );                                  

        CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
        pixelData = CGBitmapContextGetData(context);
        return self;
}


-(float) alphaAtX:(int)x y:(int)y   //get alpha component using the pointer 'pixelData' 
{
    return pixelData[(y *width + x) *4 + 3];    //+0 for red, +1 for green, +2 for blue, +3 for alpha
}

-(void)viewDidLoad { [super viewDidLoad]; UIImage *img = [UIImage imageNamed:@"MacDrive.png"]; //load image

[self initWithImage:img];   //create BitmapContext with UIImage
float alpha = [self alphaAtX:20 y:20];  //store alpha component

}

Wenn ich versuche, rot / grün / blau zu speichern, sie erweisen sich als immer 240. Und Alpha ist immer 255.

So denke ich, vielleicht ist etwas falsch mit dem Zeiger. Es kann nicht die richtigen ARGB Daten zurückgeben ich will. Irgendwelche Ideen, was ist los mit dem Code?

War es hilfreich?

Lösung

Zu allererst Sie undichte Speicher, der Pixeldata Speicher wird nie freigegeben.

Für Ihre Nutzung ist es besser, die CGContext Anrufe die Speicher verwalten zu lassen. Übergeben Sie einfach NULL I.S.O. Pixeldata, und solange Sie die Referenz auf Ihrem Kontext zählen zu halten, wird die CGBitmapContextGetData(context) gültig bleiben.

Sie alpha verwenden, als ob es der letzte Eintrag (RGBA, nicht ARGB) wurde, es als solches in der Erstellung Ihrer Kontext verwenden oder den alphaAtX Code anzupassen. Ich bin mir nicht sicher, ob Sie premultiplied wollen, wenn es nur Alpha-Werte zu überprüfen, können Sie dies nicht tun.

Alles in allem so etwas wie:

[...]
CGContextRelease(context);
context = CGBitmapContextCreate (NULL,                                                     
                                    image.size.width,
                                    image.size.height,
                                    8,    // bits per component
                                    bitmapBytesPerRow,
                                    colorSpace,
                                    kCGImageAlphaLast
                                    );
CGColorSpaceRelease( colorSpace );                                                                      

CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
pixelData = CGBitmapContextGetData(context);
[...]

mit Kontext eine Membervariable ist, auf NULL initialisiert, wird bereits ein Schritt in der richtigen Richtung sein.

Andere Tipps

Als erstes würde ich überprüfen, um zu sehen, ob der Zusammenhang von Ihrem CGBitmapContextCreate Aufruf zurückgegeben gültig ist (das heißt, stellen Sie sicher, context != NULL). Ich würde überprüfen, um auch sicherstellen, dass Ihr ursprünglich geladene Bild gültig ist (so stellen Sie sicher, img != nil).

Wenn Ihr Kontext null ist, kann es sein, weil Sie Ihre Bildgröße nicht vertretbar ist, oder auch Ihr Pixeldatenformat ist nicht verfügbar. Versuchen Sie es mit kCGImageAlphaPremultipliedLast statt?

Zweitens brauchen Sie nicht CGBitmapContextGetData verwenden - man muss nur den pixelData Zeiger Sie an erster Stelle geführt verwenden kann. Sie sollten Ihre CGContextRelease Funktion vor dem Verlassen ein Leck zu vermeiden.

initWithImage: Ihren Kontext auch

Ich stelle auch fest, dass Sie kCGImageAlphaPremultipliedFirst verwenden. Dies bedeutet, dass die Alpha-Komponente ist zuerst , nicht zuletzt, in Ihrem Bild, so dass Sie ein 0 für die Alpha-Komponente in Ihrer alphaAtX:y: Funktion versetzt werden sollen.

Gibt es irgendeine dieser Hilfe?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top