سؤال

أقوم حاليًا بإنشاء محرر صور أساسي لـ iPhone.

أنا آخذ CGImageRef من UIImage وإنشاء سياق له باستخدام الكود التالي

origImage = result.CGImage;

Iheight = CGImageGetHeight(origImage);
Iwidth = CGImageGetWidth(origImage);
IcolorSpace = CGColorSpaceCreateDeviceRGB();
IrawData = malloc(Iheight * Iwidth * 4);
IbytesPerPixel = 4;
IbytesPerRow = IbytesPerPixel * Iwidth;
IbitsPerComponent = 8;
Icontext = CGBitmapContextCreate(IrawData, Iwidth, Iheight, IbitsPerComponent,
                                 IbytesPerRow, IcolorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big
                                 );
//[bytesPerRow release];
CGContextSetBlendMode(Icontext, kCGBlendModeCopy);
CGContextDrawImage(Icontext, CGRectMake(0,0,Iwidth,Iheight),  origImage);

أنا ثم حلقة من خلال البكسل

for (int x=0; x<Iwidth; x++) {
    for (int y=0; y<Iheight; y++) {
            //and  set the alpha component to 0
            int byteIndex = (y*IbytesPerRow) + x*IbytesPerPixel;

            IrawData[byteIndex+3] = 0;

            }
}

ثم قم بإنشاء cgimageref من السياق مع

    CGImageRef imagea = CGBitmapContextCreateImage(Icontext);

وأضف cgimage إلى uiimage وتعيين إلى uiimageview

المشكلة هي أن تغيير ألفا لا يؤثر على الصورة الناتجة

إذا قمت بتغيير لون البكسل مع

IrawData[byteIndex+(0/1/2)]

يتغير اللون ، ولكن ما زلت لا أستطيع تغيير ألفا بكسل

شكرًا لك،

لا لا لا

هل كانت مفيدة؟

المحلول

لا تنسَ ألوانًا غير مستمدة قبل تغيير ألفا ، وإعادة تمييزها بعد ذلك.

تعني اللون الباريبي (الذي يُطلق عليه غالبًا "alpha premultiplied ، وهو مضلل) أن مكونات الألوان يتم تخزينها بالفعل مضروبة من قبل ألفا ، لتخفيف التركيب. تبدو عملية التركيب المعتادة (المصدر) هكذا:

result = (source.rgb * source.a) + (destination.rgb * (1.0 - destination.a));

يعني premultiplication أن الضرب الأول قد تم بالفعل ، بحيث يمكن تخطيه:

result =  source.rgb             + (destination.rgb * (1.0 - destination.a));

عندما تقوم بتغيير ألفا دون تغيير مكونات الألوان الممتازة ، فإن النتيجة لا تتغير - عندما ترسم الصورة ، لن تبدو مختلفة ، لأن الألوان لا تزال متعمدة من قبل ألفا القديم.

لذا ، فأنت بحاجة إلى عدم وجود ألوان - أي تقسيم كل منها على ألفا (كما سبق مضروبًا ، لذلك يجب عليك الآن القيام بالعكس) - قبل تغيير ألفا. ثم ، بعد تغيير ألفا ، بشكل مسبق الألوان من قبل ألفا الجديدة.

بالطبع ، هذا يعني أنه عند تغيير ألفا إلى صفر ، ستصبح جميع الألوان سوداء (r = g = b = 0). لذا ، تأكد من الاحتفاظ بالصورة الأصلية إذا كان المستخدم قد يرغب في تغييرها مرة أخرى.

من المحتمل أن يكون الأمر أكثر فاعلية ، وسيكون بالتأكيد أسهل ، فقط رسم الصورة الأصلية (دون أي تغييرات ألفا التي تم إجراؤها عليها) في أي ألفا يريد المستخدم. يمكنك القيام بذلك بواسطة تغيير Alpha العالمي لسياق العرض الخاص بك قبل أن ترسم الصورة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top