2009-03-11 4 views
22

В моем приложении для iPhone у меня есть экземпляр UIImage. Я хочу получить полученный UIImage, который является результатом первого UIImage, где один из его цветов (например, пурпурный) становится прозрачным. Как я могу это сделать?Как сделать один цвет прозрачным на UIImage?

ответ

12
-(void)changeColor 
{ 
    UIImage *temp23=[UIImage imageNamed:@"leaf.png"]; 
    CGImageRef ref1=[self createMask:temp23]; 
    const float colorMasking[6] = {1.0, 2.0, 1.0, 1.0, 1.0, 1.0}; 
    CGImageRef New=CGImageCreateWithMaskingColors(ref1, colorMasking); 
    UIImage *resultedimage=[UIImage imageWithCGImage:New]; 
} 

-(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; 
} 

Приведенный выше код проверяется, и я изменил зеленый цвет на красный цвет с помощью маски

+2

ваш код работает great.but как я изменить красный green.or любой другой цвет –

+2

Благодарим вас за хорошую функцию. Но я не мог получить истинный результат, пока не сделал это изменение: kCGImageAlphaPremultipliedFirst -> kCGImageAlphaPremultipliedLast После того, как эта функция дала мне истинный результат. :) Спасибо. – Vitaly

+0

Как изменить зеленый цвет на черный? – isarathg

1

Я никогда не делал ничего подобного, но похоже, что CGImageCreateWithMaskingColors может быть полезен здесь. Использование Core Graphics выходит за рамки того, что я могу объяснить в ответе на этом сайте; взгляните на свою документацию и найдите учебники в Интернете.

10

После использования ваших функций, я нашел более простой способ сделать прозрачный фон для UIImage :)

Например, у вас есть PNG-изображение с черным фоном, и вы хотите сделать этот фон прозрачным на экране.

Вы можете попробовать это:

UIImage * image = [UIImage imageNamed:@"image.png"]; 

const CGFloat colorMasking[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 
image = [UIImage imageWithCGImage: CGImageCreateWithMaskingColors(image.CGImage, colorMasking)]; 

Вы получили изображение с прозрачным фоном.

Это все :)

+3

Это делает черный цвет белым цветом не сделать его прозрачным .... –

+0

отлично! Он отлично работает для меня! – JonasG

+0

Разве это не так, как небольшая часть принятого ответа, и я согласен с @AshishMathur, что это не полное решение. – PKCLsoft

11

эта функция может работать!

-(UIImage *)changeWhiteColorTransparent: (UIImage *)image 
{ 
    CGImageRef rawImageRef=image.CGImage; 

    const float colorMasking[6] = {222, 255, 222, 255, 222, 255}; 

    UIGraphicsBeginImageContext(image.size); 
    CGImageRef maskedImageRef=CGImageCreateWithMaskingColors(rawImageRef, colorMasking); 
    { 
     //if in iphone 
     CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0.0, image.size.height); 
     CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0); 
    } 

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, image.size.width, image.size.height), maskedImageRef); 
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); 
    CGImageRelease(maskedImageRef); 
    UIGraphicsEndImageContext();  
    return result; 
} 
+1

Блестящий! Только то, о чем просили. Работал из коробки! Благодарю. – PKCLsoft

+5

Это делает все мое изображение прозрачным. Я что-то упускаю? –

32

ОК. Попробовав, я не знаю, сколько версий этих решений у меня есть собственная индивидуальная версия. Я нашел, что решение от @yubenyi работает достаточно хорошо, но если вы хотите вывести результат из своей функции changeWhiteColorTransparent() и передать его обратно, это не сработает.

Мой первый шаг состоял в том, чтобы изменить его функцию, чтобы принять определенный цвет и толерантность, чтобы вызывающий мог указать диапазон цветов, чтобы сделать прозрачным. Это работало нормально, почти без изменений, но я обнаружил, что вывод не является допустимым изображением для прохождения через тот же код со вторым диапазоном цветов.

После многих проб и ошибок, я получил эту работу, выполнив замену цвета сам. Я сопротивлялся этому, потому что это казалось слишком тяжелой работой, когда есть API для этого, но они не всегда ведут себя так, как вы хотите. В частности, вывод CGImageCreateWithMaskingColors() не может использоваться в качестве входа в другой вызов той же функции. Я не мог понять, почему, но я думаю, что это как-то связано с альфа-каналом.

В любом случае, мое решение:

- (UIImage*) replaceColor:(UIColor*)color inImage:(UIImage*)image withTolerance:(float)tolerance { 
    CGImageRef imageRef = [image CGImage]; 

    NSUInteger width = CGImageGetWidth(imageRef); 
    NSUInteger height = CGImageGetHeight(imageRef); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    NSUInteger bytesPerPixel = 4; 
    NSUInteger bytesPerRow = bytesPerPixel * width; 
    NSUInteger bitsPerComponent = 8; 
    NSUInteger bitmapByteCount = bytesPerRow * height; 

    unsigned char *rawData = (unsigned char*) calloc(bitmapByteCount, sizeof(unsigned char)); 

    CGContextRef context = CGBitmapContextCreate(rawData, width, height, 
               bitsPerComponent, bytesPerRow, colorSpace, 
               kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 

    CGColorRef cgColor = [color CGColor]; 
    const CGFloat *components = CGColorGetComponents(cgColor); 
    float r = components[0]; 
    float g = components[1]; 
    float b = components[2]; 
    //float a = components[3]; // not needed 

    r = r * 255.0; 
    g = g * 255.0; 
    b = b * 255.0; 

    const float redRange[2] = { 
     MAX(r - (tolerance/2.0), 0.0), 
     MIN(r + (tolerance/2.0), 255.0) 
    }; 

    const float greenRange[2] = { 
     MAX(g - (tolerance/2.0), 0.0), 
     MIN(g + (tolerance/2.0), 255.0) 
    }; 

    const float blueRange[2] = { 
     MAX(b - (tolerance/2.0), 0.0), 
     MIN(b + (tolerance/2.0), 255.0) 
    }; 

    int byteIndex = 0; 

    while (byteIndex < bitmapByteCount) { 
     unsigned char red = rawData[byteIndex]; 
     unsigned char green = rawData[byteIndex + 1]; 
     unsigned char blue = rawData[byteIndex + 2]; 

     if (((red >= redRange[0]) && (red <= redRange[1])) && 
      ((green >= greenRange[0]) && (green <= greenRange[1])) && 
      ((blue >= blueRange[0]) && (blue <= blueRange[1]))) { 
      // make the pixel transparent 
      // 
      rawData[byteIndex] = 0; 
      rawData[byteIndex + 1] = 0; 
      rawData[byteIndex + 2] = 0; 
      rawData[byteIndex + 3] = 0; 
     } 

     byteIndex += 4; 
    } 

    CGImageRef imgref = CGBitmapContextCreateImage(context); 
    UIImage *result = [UIImage imageWithCGImage:imgref]; 

    CGImageRelease(imgref); 
    CGContextRelease(context); 
    free(rawData); 

    return result; 
} 
+3

Это мой любимый ответ для меня, поскольку может быть терпимость. Nota: допуск между 0 и 255, поэтому он не имеет эффекта ниже 1. Теперь гладкая версия будет идеальной! – Diwann

+0

Спасибо, что он работает идеально ... я дал +1 @pkclSoft – Babul

+0

Ты спас мой день .... Приветствия .. – Maulik

16

Это подстройка кода yubenyi, которая будет работать с несколькими проходами. Он обрабатывает альфа-канал перед обработкой, преобразовывая изображение в несжатый jpeg. Также добавлены некоторые комментарии о том, как работает выбор цветового диапазона.

-(UIImage *)changeWhiteColorTransparent: (UIImage *)image 
{ 
    //convert to uncompressed jpg to remove any alpha channels 
    //this is a necessary first step when processing images that already have transparency 
    image = [UIImage imageWithData:UIImageJPEGRepresentation(image, 1.0)]; 
    CGImageRef rawImageRef=image.CGImage; 
    //RGB color range to mask (make transparent) R-Low, R-High, G-Low, G-High, B-Low, B-High 
    const double colorMasking[6] = {222, 255, 222, 255, 222, 255}; 

    UIGraphicsBeginImageContext(image.size); 
    CGImageRef maskedImageRef=CGImageCreateWithMaskingColors(rawImageRef, colorMasking); 

    //iPhone translation 
    CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0.0, image.size.height); 
    CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0); 

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, image.size.width, image.size.height), maskedImageRef); 
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); 
    CGImageRelease(maskedImageRef); 
    UIGraphicsEndImageContext();  
    return result; 
} 
+0

Что такое imgLoad в первой строке кода? – Dejell

+0

Предполагалось, что это будет «образ». Я сделал редактирование. Спасибо за исправление! – bgolson

+1

работал для меня!Но мне пришлось изменить 'const float colorMasking [6]' на 'const double colorMasking [6]' – moobi

1

на основе @PKCLsoft «s превосходный ответ, я сделал правку, где он только делает белый цвет прозрачным, но это делает альфа основан на том, как„белый“пиксель. Это может пригодиться, когда вы пытаетесь сделать маску из черно-белого изображения, поэтому она даст гладкие края текста или фигур.

- (UIImage *)makeWhiteColorTransparentInImage:(UIImage *)image { 
    CGImageRef imageRef = [image CGImage]; 

    NSUInteger width = CGImageGetWidth(imageRef); 
    NSUInteger height = CGImageGetHeight(imageRef); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    NSUInteger bytesPerPixel = 4; 
    NSUInteger bytesPerRow = bytesPerPixel * width; 
    NSUInteger bitsPerComponent = 8; 
    NSUInteger bitmapByteCount = bytesPerRow * height; 

    unsigned char *rawData = (unsigned char*) calloc(bitmapByteCount, sizeof(unsigned char)); 

    CGContextRef context = CGBitmapContextCreate(rawData, width, height, 
              bitsPerComponent, bytesPerRow, colorSpace, 
              kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 

    int byteIndex = 0; 

    while (byteIndex < bitmapByteCount) { 
     unsigned char red = rawData[byteIndex]; 
     unsigned char green = rawData[byteIndex + 1]; 
     unsigned char blue = rawData[byteIndex + 2]; 
     unsigned char alpha = rawData[byteIndex + 3]; 

     if (alpha == 0.0) { 
      rawData[byteIndex + 3] = 0.0; 
     } else { 
      rawData[byteIndex + 3] = 255.0 - (red + green + blue)/3.0; 
     } 

     byteIndex += 4; 
    } 

    CGImageRef imgref = CGBitmapContextCreateImage(context); 
    UIImage *result = [UIImage imageWithCGImage:imgref]; 

    CGImageRelease(imgref); 
    CGContextRelease(context); 
    free(rawData); 

    return result; 
} 

Я надеюсь, что это помогает кто-нибудь :)

1

Swift 4: (для белого маскирования)

extension UIImage { 
func imageByMakingWhiteBackgroundTransparent() -> UIImage? { 

    let image = UIImage(data: UIImageJPEGRepresentation(self, 1.0)!)! 
    let rawImageRef: CGImage = image.cgImage! 

    let colorMasking: [CGFloat] = [222, 255, 222, 255, 222, 255] 
    UIGraphicsBeginImageContext(image.size); 

    let maskedImageRef = rawImageRef.copy(maskingColorComponents: colorMasking) 
    UIGraphicsGetCurrentContext()?.translateBy(x: 0.0,y: image.size.height) 
    UIGraphicsGetCurrentContext()?.scaleBy(x: 1.0, y: -1.0) 
    UIGraphicsGetCurrentContext()?.draw(maskedImageRef!, in: CGRect.init(x: 0, y: 0, width: image.size.width, height: image.size.height)) 
    let result = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return result 

    } 
} 
Смежные вопросы