【问题标题】:ios: change the colors of a UIImageios:更改 UIImage 的颜色
【发布时间】:2012-09-05 22:46:51
【问题描述】:

我正在开发一个 Iphone 应用程序。

我有代表符号的 png 图片。符号全黑,背景透明。

有没有办法可以将黑色变成另一种颜色?我正在寻找的是可以帮助我选择我想要的颜色的东西,并且在使用符号时(在 UIImage 中)我可以让它们显示为我选择的颜色。

我四处搜索,发现了一个名为 OpenCV 的框架,它可以处理图像,但我不知道如何为图片重新着色。

非常感谢任何帮助和建议。

谢谢

【问题讨论】:

  • 你为什么不在photoshop中编辑它?这对你来说更容易
  • 我有 1500 个符号,每周都在变化。我不确定这是个好主意

标签: objective-c ios opencv colors uiimage


【解决方案1】:

要使用objective-c 处理图像,主要你必须使用Quartz 2D/CoreGraphics 框架。我想这将是您完成任务的最简单方法。

Quartz 2D 指南的链接是here ,该指南非常全面。只需看看用颜色填充位图的某个地方。

我的博客里也有一些关于重度图像处理的记录,你可以看看,它可能会有所帮助。 http://levonp.blogspot.de/2012/05/quartz-getting-diff-images-of-two.html

当然,你也可以使用更高级的东西,如 OpenGL、OpenCV 等。

【讨论】:

    【解决方案2】:

    您可以创建存储 UIImageView 并更改 UIview 背景颜色的 UIView。

    UIView *viewForImage = ....;
    UIImageView *imageView = .....;
    ...
    
    [viewForImage addSubview: imageView];
    [self.view addSubview:viewForImage];
    ...
    

    然后使用例如

    [viewForImage setBackgroundColor: [UIColor redColor]];
    

    【讨论】:

      【解决方案3】:

      你可以使用这个类别文件来改变图像的整个颜色......

      .h 文件:

      #import <UIKit/UIKit.h>
      
      @interface UIImage (AddtionalFunctionalities)
      
      //TintColor...
      - (UIImage *)imageWithTint:(UIColor *)tintColor;
      //scale and resize...
      -(UIImage*)scaleToSize:(CGSize)size;
      
      @end
      

      .m 文件:

      #import "UIImage+AddtionalFunctionalities.h"
      
      @implementation UIImage (AddtionalFunctionalities)
      
      
      - (UIImage *)imageWithTint:(UIColor *)tintColor 
      {
          // Begin drawing
          CGRect aRect = CGRectMake(0.f, 0.f, self.size.width, self.size.height);
          CGImageRef alphaMask;
      
          //
          // Compute mask flipping image
          //
          {
              UIGraphicsBeginImageContext(aRect.size);        
              CGContextRef c = UIGraphicsGetCurrentContext(); 
      
              // draw image
              CGContextTranslateCTM(c, 0, aRect.size.height);
              CGContextScaleCTM(c, 1.0, -1.0);
              [self drawInRect: aRect];
      
              alphaMask = CGBitmapContextCreateImage(c);
      
              UIGraphicsEndImageContext();
          }
      
          //
          UIGraphicsBeginImageContext(aRect.size);
      
          // Get the graphic context
          CGContextRef c = UIGraphicsGetCurrentContext(); 
      
          // Draw the image
          [self drawInRect:aRect];
      
          // Mask
          CGContextClipToMask(c, aRect, alphaMask);
      
          // Set the fill color space
          CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
          CGContextSetFillColorSpace(c, colorSpace);
      
          // Set the fill color
          CGContextSetFillColorWithColor(c, tintColor.CGColor);
      
          UIRectFillUsingBlendMode(aRect, kCGBlendModeNormal);
      
          UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
          UIGraphicsEndImageContext();    
      
          // Release memory
          CGColorSpaceRelease(colorSpace);
          CGImageRelease(alphaMask);
      
          return img;
      }
      
      
      -(UIImage*)scaleToSize:(CGSize)size
      {
          // Create a bitmap graphics context
          // This will also set it as the current context
          UIGraphicsBeginImageContext(size);
      
          // Draw the scaled image in the current context
          [self drawInRect:CGRectMake(0, 0, size.width, size.height)];
      
          // Create a new image from current context
          UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
      
          // Pop the current context from the stack
          UIGraphicsEndImageContext();
      
          // Return our new scaled image
          return scaledImage;
      }
      
      @end
      

      方法调用将是:

       self.outputImage.image=[sourceImage imageWithTint:[UIColor redColor]];
      

      如果你想使用图片,请使用这个:

      self.outputImage.image=[sourceImage imageWithTint:[UIColor colorWithPatternImage:[UIImage imageNamed: @"red.jpg"]]];
      

      希望对你有帮助...

      【讨论】:

      • 注意:这会将整个图像更改为一种颜色...(例如黑色,蓝色)
      • kCGBlendModeNormal 应该是 kCGBlendModeColor
      • 谢谢你.. 就像一个魅力.. :) 我希望我能投票两次。
      【解决方案4】:

      你想改变删除/一种特定的颜色意味着使用下面的类别....

      .h 文件:

      #import <UIKit/UIKit.h>
      
      @interface UIImage (Color)
      
      + (UIImage*)setBackgroundImageByColor:(UIColor *)backgroundColor withFrame:(CGRect )rect;
      
      
      + (UIImage*) replaceColor:(UIColor*)color inImage:(UIImage*)image withTolerance:(float)tolerance;
      
      +(UIImage *)changeWhiteColorTransparent: (UIImage *)image;
      
      +(UIImage *)changeColorTo:(NSMutableArray*) array Transparent: (UIImage *)image;
      
      //resizing Stuff...
      + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize;
      
      @end
      

      .m 文件

      #import <QuartzCore/QuartzCore.h>
      #import "UIImage+Color.h"
      
      @implementation UIImage (Color)
      
      
      
      
      + (UIImage* )setBackgroundImageByColor:(UIColor *)backgroundColor withFrame:(CGRect )rect{
      
          // tcv - temporary colored view
          UIView *tcv = [[UIView alloc] initWithFrame:rect];
          [tcv setBackgroundColor:backgroundColor];
      
      
          // set up a graphics context of button's size
          CGSize gcSize = tcv.frame.size;
          UIGraphicsBeginImageContext(gcSize);
          // add tcv's layer to context
          [tcv.layer renderInContext:UIGraphicsGetCurrentContext()];
          // create background image now
          UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
           UIGraphicsEndImageContext();
      
           return image;
      //    [tcv release];
      
      }
      
      
      
      
      
      + (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;
          }
      
          UIImage *result = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
      
          CGContextRelease(context);
          free(rawData);
      
          return result;
      }
      
      +(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;
      }
      
      
      
      
      +(UIImage *)changeColorTo:(NSMutableArray*) array Transparent: (UIImage *)image
      {
          CGImageRef rawImageRef=image.CGImage;
      
      //    const float colorMasking[6] = {222, 255, 222, 255, 222, 255};
      
           const float colorMasking[6] = {[[array objectAtIndex:0] floatValue], [[array objectAtIndex:1] floatValue], [[array objectAtIndex:2] floatValue], [[array objectAtIndex:3] floatValue], [[array objectAtIndex:4] floatValue], [[array objectAtIndex:5] floatValue]};
      
      
          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;
      }
      
      + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
          //UIGraphicsBeginImageContext(newSize);
          UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
          [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
          UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
          UIGraphicsEndImageContext();
          return newImage;
      }
      
      
      
      @end
      

      我通过此代码将移除的白色更改为透明......

      电话将是...

       self.rawImage.image=[UIImage changeWhiteColorTransparent:originalStateImage];
      

      我希望这个想法对你有所帮助....

      【讨论】:

      • 您能否举例说明changeColorTo 方法的用法。即数组参数应该包含什么?
      • 我需要在运行时用不同颜色替换所有白色像素,保持 alpha 值相同。例如RGBA 为 255,255,255,255 -> 128,128,128,255。但是 RGBA 为 255,255,255,128 -> 128,128,128,128。你的changeColorTo方法是我想要的吗?
      • 如果您希望图像在 Retina 设备上看起来清晰,您应该使用 UIGraphicsBeginImageContextWithOptions()
      • 感谢作者。这是该代码可能来自的存储库:github.com/AckeeCZ/ACKategories/blob/master/UIImage%2BColor.h
      • 链接搞砸了。 github.com/AckeeCZ/ACKategories/tree/master/ACKategories/UIKit有问题的类别在UIImage+Color.h
      【解决方案5】:

      最简单最短的:

      当您与UIImageView 打交道时,该怎么做:

      Obj-C:

      theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
      [theImageView setTintColor:[UIColor redColor]];
      

      斯威夫特:

      let theImageView = UIImageView(image: UIImage(named:"foo")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate))
      theImageView.tintColor = UIColor.redColor()
      

      【讨论】:

      • 我同意这一点。漂亮。
      • 我第三!简直美极了。不仅在它的简单性上,而且在它的效果上:一个很好的平滑着色效果,没有像素化。非常感谢 Skywinder!
      • 简洁优雅。很好的答案。
      • 该问题要求您对 UIImage 对象而不是 UIImageView 执行背景颜色更改。在某些情况下,您希望能够做到这一点,而不是在视图容器上设置色调。
      • 这就是为什么我们也应该阅读不被接受的答案。绿色刻度很烂@stackoverflow
      【解决方案6】:

      设置图像渲染模式,然后为颜色目的使用 tintcolor 属性。

      yourImageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
      [yourImageView setTintColor:[UIColor redColor]];
      

      【讨论】:

        【解决方案7】:

        更改图像颜色的非常简单的解决方案。想法:UIImage 和 UIImageView 的扩展。

        Swift 3,Xcode 8.1。 https://stackoverflow.com/a/40884483/4488252

        我的回答中的代码示例(上面的链接):

        // use extension UIImage
        newImageView = createNewImageView(x: 100)
        newImageView.image =  UIImage(named: "Apple")?.imageWithColor(newColor: UIColor.blue)
        
        // use extension UIImageView
        newImageView = createNewImageView(x: 160)
        newImageView.image =  UIImage(named: "Apple")
        newImageView.imageColor = UIColor.green
        

        【讨论】:

          【解决方案8】:

          适用于 iOS 13.0

          Obj-C:

          self.yourImageView.image = [self.yourImageView.image imageWithTintColor:[UIColor.redColor]];
          

          斯威夫特:

          yourImageView.image = yourImageView.image.withTintColor(UIColor.red);
          

          如果图片来自 Asset Catalog,您可以在 Attribute Inspector 中更改渲染

          【讨论】:

            猜你喜欢
            • 2016-08-11
            • 1970-01-01
            • 2023-03-18
            • 2021-09-09
            • 1970-01-01
            • 1970-01-01
            • 2014-11-24
            • 2018-08-20
            • 1970-01-01
            相关资源
            最近更新 更多