في الكوارتز 2D، هل من الممكن إخفاء صورة عن طريق إزالة كل شيء ولكن قناة اللون التي تريدها؟

StackOverflow https://stackoverflow.com/questions/913719

سؤال

لذلك حاولت استخدام وظيفة الكوارتز CGIMAGEREATEWithmaskingColors، ولكنه مشكلة فقط هو أنه يخفي مجموعة اللون التي تختارها.

أريد أن أقنع كل شيء ولكن نطاق اللون الذي أختاره. على سبيل المثال، أريد إظهار كل الألوان الحمراء في صورة ولكن إزالة القنوات الأخرى (الأخضر والأزرق).

أنا أفعل هذا في الهدف، وأنا مستجد لذلك من فضلك أعطني أمثلة :)

أي مساعدة يحظى بتقدير كبير.

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

المحلول

استخدم هذه الأساليب. وجدهم في أحد المشاركات حتى الآن.

-(void)changeColor
{
    UIImage *temp23=Image;//Pass your image here
    CGImageRef ref1=[self createMask:temp23];
    const float colorMasking[6] = {1.0, 3.0, 1.0, 2.0, 2.0, 3.0};
    CGImageRef New=CGImageCreateWithMaskingColors(ref1, colorMasking);
    UIImage *resultedimage=[UIImage imageWithCGImage:New];
    EditImageView.image = resultedimage;
    [EditImageView setNeedsDisplay];
}

-(CGImageRef)createMask:(UIImage*)temp
{


    CGImageRef ref=temp.CGImage;
    int mWidth=CGImageGetWidth(ref);
    int mHeight=CGImageGetHeight(ref);
    int count=mWidth*mHeight*4;
    void *bufferdata=malloc(count);

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

    CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4, colorSpaceRef, kCGImageAlphaPremultipliedFirst); 

    CGRect rect = {0,0,mWidth,mHeight};
    CGContextDrawImage(cgctx, rect, ref); 
    bufferdata = CGBitmapContextGetData (cgctx);

    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bufferdata, mWidth*mHeight*4, NULL);
    CGImageRef savedimageref = CGImageCreate(mWidth,mHeight, 8, 32, mWidth*4, colorSpaceRef, bitmapInfo,provider , NULL, NO, renderingIntent);
    CFRelease(colorSpaceRef);
    return savedimageref;
}

ثم استدعاء طريقة Changecolor على أزرار انقر فوق الحدث ومعرفة النتيجة

نصائح أخرى

لقد وجدت الإجابة عن مشكلتي أعلاه، اتبع الرمز أعلاه لراهول مع بعض التغييرات لتعيين اللون الخاص بك،

-(void)changeColor
{
    UIImage *temp23=Image;//Pass your image here
    CGImageRef ref1=[self createMask:temp23];
    const float colorMasking[6] = {1.0, 3.0, 1.0, 2.0, 2.0, 3.0};
    CGImageRef New=CGImageCreateWithMaskingColors(ref1, colorMasking);
    UIImage *resultedimage=[UIImage imageWithCGImage:New];
    EditImageView.image = resultedimage;
    [EditImageView setNeedsDisplay];
}

-(CGImageRef)createMask:(UIImage*)temp
{
   CGImageRef ref=temp.CGImage;
   int mWidth=CGImageGetWidth(ref);
   int mHeight=CGImageGetHeight(ref);
   int count=mWidth*mHeight*4;
   void *bufferdata=malloc(count);

   CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
   CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
   CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

   CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4,colorSpaceRef, kCGImageAlphaPremultipliedLast); 
   CGRect rect = {0,0,mWidth,mHeight};  
   CGContextDrawImage(cgctx, rect, ref); 
   CGContextSaveGState(cgctx);  
   CGContextSetBlendMode(cgctx, kCGBlendModeColor); 
   CGContextSetRGBFillColor (cgctx, 1.0, 0.0, 0.0, 1.0);
   CGContextFillRect(cgctx, rect);


   bufferdata = CGBitmapContextGetData (cgctx);
   const float colorMasking[6] = {1.0, 3.0, 1.0, 2.0, 2.0, 3.0};
   CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bufferdata, mWidth*mHeight*4, NULL);
   CGImageRef savedimageref = CGImageCreate(mWidth,mHeight, 8, 32, mWidth*4, colorSpaceRef, bitmapInfo,provider , NULL, NO, renderingIntent);
   CFRelease(colorSpaceRef);
   return savedimageref;
}

أمم...

قد أكون في عداد المفقودين شيئا ما، لكنني لا أعتقد أن الإجابات المقدمة تنطبق على السؤال. تصبح الاستجابة الثانية أقرب إلى العلامة، ولكنها تحتوي على شفرة زائفة لا علاقة لها بالحلول.

ال createMask الطريقة تجعل نسخة من الصورة الأصلية على افتراض ألفا في وضع LSB. يقوم Changecolor بإجراء مكالمة اخفاء لا سيعمل الكثير على صورة RGB - أساسا سوداء فقط سيتم ملثمين (أي ثلاث مرات RGB في نطاق / مجموعات من (1،1،2) إلى (3، 3، 2،1)).

أنا أظن أن التحول الأحمر الذي يتم ملاحظته هو بسبب المعلمة

kCGImageAlphaPremultipliedFirst

على الخط

CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4, colorSpaceRef, kCGImageAlphaPremultipliedFirst);

بسبب العلاج غير السليم لقناة ألفا. إذا في changeColor طريقة قمت بتعديل الكتلة

CGImageRef ref1=[self createMask:temp23];
const float colorMasking[6] = {1.0, 3.0, 1.0, 2.0, 2.0, 3.0};
CGImageRef New=CGImageCreateWithMaskingColors(ref1, colorMasking);
UIImage *resultedimage=[UIImage imageWithCGImage:New];
EditImageView.image = resultedimage;

أن تكون

CGImageRef ref1=[self createMask:temp23];
UIImage *resultedimage=[UIImage imageWithCGImage:ref];
EditImageView.image = resultedimage;

لن ترى أي فرق في الشاشة. تغيير cgbitmapinfo ثابت ل kCGImageAlphaPremultipliedLast يجب عرض الصورة بشكل صحيح باستخدام أي من كتل التعليمات البرمجية أعلاه.

يحصل الاستجابة التالية أقرب قليلا من ما يطلبه المرجع، ولكن من حيث التأثير البصري، وليس البيانات الفعلية. هنا الرمز المناسب في createMask يكون

CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4,colorSpaceRef, kCGImageAlphaPremultipliedLast);

الذي يعرض الصورة بشكل صحيح، تليها

CGContextSetBlendMode(cgctx, kCGBlendModeColor); 
CGContextSetRGBFillColor (cgctx, 1.0, 0.0, 0.0, 1.0);
CGContextFillRect(cgctx, rect);

ثم المنطق بناء الصورة. تتراكم المنطق المزيج صبغة حمراء على الصورة الأصلية، وتحقيق تأثير مماثل كقناة ألفا في غير محله في الاستجابة الأصلية. هذا لا يزال حقا ليس ما يطلبه المرجع، وهو ما يخفي قنات واحد أو أكثر، وليس مزج الألوان.

هذا يبقى حقا لتحديد قيم القناة للألوان غير المرغوب فيها إلى الصفر. إليك مثال لإرجاع القناة الحمراء فقط كما طلبات المرجع؛ الافتراض هو أن تنسيق البكسل هو ABGR:

- (CGImageRef) redChannel:(CGImageRef)image 
{
    CGDataProviderRef provider = CGImageGetDataProvider(image);
    NSMutableData* data = (id)CGDataProviderCopyData(provider);

    int width = CGImageGetWidth(image);
    int height = CGImageGetHeight(image);

    [data autorelease];

    // get a mutable reference to the image data
    uint32_t* dwords = [data mutableBytes];

    for (size_t idx = 0; idx < width*height; idx++) {
        uint32_t* pixel = &dwords[idx];
        // perform a logical AND of the pixel with a mask that zeroes out green and blue pixels
        *pixel &= 0x000000ff;
    }

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

    // now create a new image using the masked original data
    CGDataProviderRef iprovider = CGDataProviderCreateWithData(NULL, dwords, width*height*4, NULL);
    CGImageRef savedimageref = CGImageCreate(width, height, 8, 32, width*4, colorSpaceRef, bitmapInfo, iprovider, NULL, NO, renderingIntent);
    CGColorSpaceRelease(colorSpaceRef);
    CGDataProviderRelease(iprovider);

    return savedimageref;
}

ملخص جيد لعمليات bitwise يمكن العثور عليها هنا.

كما هو مدبب هنا, ، قد تحتاج إلى تغيير هيكل القناع اعتمادا على طلب LSB / MSB في البتات في بكسل. يفترض هذا المثال 32 بت بكسل من PNG iPhone القياسي.

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