كيفية سحب مكون Argb من BitmapContext على iPhone؟
سؤال
أحاول الحصول على مكونات Argb من cgbitmapcontext مع الرموز التالية:
-(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
}
- (الفراغ) ViewDidIDLoad {[Super ViewDidLoad]؛ uiimage * img = [uiimage imagenamed: @ "macdrive.png"]؛ //تحميل الصورة
[self initWithImage:img]; //create BitmapContext with UIImage
float alpha = [self alphaAtX:20 y:20]; //store alpha component
}
عندما أحاول تخزين الأحمر / الأخضر / الأزرق، فإنها تتحول دائما إلى 240. و Alpha دائما 255.
لذلك أعتقد أن هناك خطأ ما في المؤشر. لا يمكن أن تعيد بيانات ARGB الصحيحة التي أريدها. أي أفكار حول ما هو الخطأ في الكود؟
المحلول
بادئ ذي بدء، تقوم بتسريب الذاكرة، لا يتم تحرير ذاكرة Pixeldata أبدا.
بالنسبة لاستخدامك، من الأفضل السماح ل Cgcontext يدعو إلى إدارة الذاكرة. ما عليك سوى تمرير NULL ISO Pixeldata، طالما أنك تبقي المرجع عد في سياقك، CGBitmapContextGetData(context)
سوف تبقى صالحة.
كنت تستخدم Alpha كما لو كان آخر إدخال (RGBA، وليس Argb)، فاستخدمه على هذا النحو في إنشاء سياقك، أو تكييف alphaAtX
الشفرة. لست متأكدا مما إذا كنت تريد مسببات العمل، إذا كان الأمر فقط لفحص قيم ألفا، فأنت لا تفعل ذلك.
كل شيء في كل شيء مثل:
[...]
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);
[...]
مع كونه سياق كونه متغيرا في الأعضاء، فإن تهيئة فارغة، ستكون بالفعل خطوة في الاتجاه الصحيح.
نصائح أخرى
أولا، سوف تحقق لمعرفة ما إذا كان السياق عاد من CGBitmapContextCreate
الاتصال صالح (وهذا هو، تأكد context != NULL
). أود أن تحقق أيضا للتأكد من أن الصورة المحملة في الأصل صالحة (لذلك، تأكد img != nil
).
إذا كان سياقك NIL، فقد يكون ذلك لأن حجم صورتك غير معقول، وإلا فإن تنسيق بيانات Pixel غير متوفر. جرب استخدام kCGImageAlphaPremultipliedLast
في حين أن؟
ثانيا، لا تحتاج إلى استخدام CGBitmapContextGetData
- يمكنك فقط استخدام pixelData
مؤشر مررت في المقام الأول. يجب عليك أيضا CGContextRelease
سياقك قبل مغادرة الخاص بك initWithImage:
وظيفة لتجنب التسرب.
أنا أيضا لاحظ أنك تستخدم kCGImageAlphaPremultipliedFirst
. وبعد هذا يعني أن مكون ألفا هو أول, ، لا تدوم، في صورتك، لذلك تريد إزاحة من 0 مكون ألفا في alphaAtX:y:
وظيفة.
هل أي من تلك المساعدة؟