美文网首页iOS Developer
iOS开发图片RGB调整

iOS开发图片RGB调整

作者: sixthElement | 来源:发表于2016-06-13 18:19 被阅读1086次

    今天突然有需求,需要显示手机附近的HUD路况,由于要反射到HUD上,所以颜色必须以蓝,黑,白为主,显示效果才最好。无奈高德地图的路况地图不支持背景颜色的调整,只能想办法把mapView截取成imageView并且改变imageView的RGB来实现,试试吧。。。

    首先寻找到截图:

    UIImage *screenshotImage = [self.mapView takeSnapshotInRect:self.view.bounds];
    

    为数据源;

    其次找到方法:
    <pre>void ProviderReleaseData (void *info, const void data, size_t size)
    {
    free((void
    )data);
    }

    • (UIImage) imageBlackToTransparent:(UIImage) image
      {
      // 分配内存
      const int imageWidth = image.size.width;
      const int imageHeight = image.size.height;

      size_t bytesPerRow = imageWidth * 4;

      uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);

      // 创建context
      CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
      CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,
      kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
      CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);

      // 遍历像素
      int pixelNum = imageWidth * imageHeight;
      uint32_t* pCurPtr = rgbImageBuf;
      for (int i = 0; i < pixelNum; i++, pCurPtr++)
      {
      if ((pCurPtr & 0x00ff0000)>>16 == 237)
      {
      uint8_t
      ptr = (uint8_t*)pCurPtr;
      ptr[3] = 0x00; //0~255
      ptr[2] = 0x00;
      ptr[1] = 0x00;
      //ptr[0] = 0x00;
      }
      }

      // 将内存转成image
      CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
      CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpace,
      kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider,
      NULL, true, kCGRenderingIntentDefault);
      CGDataProviderRelease(dataProvider);

      UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];

      // 释放
      CGImageRelease(imageRef);
      CGContextRelease(context);
      CGColorSpaceRelease(colorSpace);

      return resultUIImage;
      }</pre>
      这里面(*pCurPtr & 0x00ff0000)>>16==237是像素点的R值==237时,并把这个像素点设置为RGB000的黑色。

    但是转化完毕的图片会毛毛躁躁,很可能会不规则,而且如何得到我们想转换的颜色的R值呢?

    我是这样做的,把图片截图后,写了一个demo,具体是这样:
    <pre>-(void)viewDidLoad {
    [super viewDidLoad];
    _dic = [[NSMutableDictionary alloc]init];
    for (int i = 0; i++; i<=255) {
    [_dic setObject:[NSNumber numberWithInt:0] forKey:[NSString stringWithFormat:@"%d",i]];
    }
    [self startCopyImage];

    int tempX = 0;
    int j = 0;
    while (j<=255) {
    j++;
    NSLog(@"%d",[[_dic objectForKey:[NSString stringWithFormat:@"%d",j]] intValue]);
    if ([[_dic objectForKey:[NSString stringWithFormat:@"%d",j]] intValue]>=tempX) {
    tempX = [[_dic objectForKey:[NSString stringWithFormat:@"%d",j]] intValue];
    }
    }

    NSLog(@"X---%d",tempX);
    NSLog(@"Y---%@",_dic);
    

    }</pre>

    这样X---打印出的是这个图片中像素点R值出现最多的次数,搜索打印结果后就可以在Y---中看到哪个像素点最常见,此时提供的截图最好为大部分都是你想去掉的颜色,这样就得出这个颜色的R值。稍微改进排序后你可以对图片的前几名多颜色的R值都德刀,并且利用上面的方法改变颜色。

    还有找到一个判断像素点rgb来判断这个界面上出现最多的颜色 代码如下

    -(UIColor*)mostColor:(UIImage*)image{
    #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
    int bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
    #else
    int bitmapInfo = kCGImageAlphaPremultipliedLast;
    #endif
    
    //第一步 先把图片缩小 加快计算速度. 但越小结果误差可能越大
    CGSize thumbSize=CGSizeMake(300, 300);
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL,
                                                 thumbSize.width,
                                                 thumbSize.height,
                                                 8,//bits per component
                                                 thumbSize.width*4,
                                                 colorSpace,
                                                 bitmapInfo);
    
    CGRect drawRect = CGRectMake(0, 0, thumbSize.width, thumbSize.height);
    CGContextDrawImage(context, drawRect, image.CGImage);
    CGColorSpaceRelease(colorSpace);
    
    
    
    //第二步 取每个点的像素值
    unsigned char* data = CGBitmapContextGetData (context);
    
    if (data == NULL) return nil;
    
    NSCountedSet *cls=[NSCountedSet setWithCapacity:thumbSize.width*thumbSize.height];
    
    for (int x=0; x<thumbSize.width; x++) {
        for (int y=0; y<thumbSize.height; y++) {
            
            int offset = 4*(x*y);
            
            int red = data[offset];
            int green = data[offset+1];
            int blue = data[offset+2];
            int alpha =  data[offset+3];
            
            NSArray *clr=@[@(red),@(green),@(blue),@(alpha)];
            [cls addObject:clr];
            
        }
    }
    CGContextRelease(context);
    
    
    //第三步 找到出现次数最多的那个颜色
    NSEnumerator *enumerator = [cls objectEnumerator];
    NSArray *curColor = nil;
    
    NSArray *MaxColor=nil;
    NSUInteger MaxCount=0;
    
    while ( (curColor = [enumerator nextObject]) != nil )
    {
        NSUInteger tmpCount = [cls countForObject:curColor];
        
        if ( tmpCount < MaxCount ) continue;
        
        MaxCount=tmpCount;
        MaxColor=curColor;
        
    }
    
    return [UIColor colorWithRed:([MaxColor[0] intValue]/255.0f) green:([MaxColor[1] intValue]/255.0f) blue:([MaxColor[2] intValue]/255.0f) alpha:([MaxColor[3] intValue]/255.0f)];}
    

    此时我们只需要截图需要的主色调成uiimage,便能方便的获取这种颜色的色调
    并且在上面改变颜色的方法中进行判断

    (*pCurPtr & 0xFFFFFF00) == 0XF8EEE200

    或者

    ((pCurPtr & 0xFF000000)>>24 == 248 && (pCurPtr & 0x00FF0000)>>16 == 238 (*pCurPtr & 0x0000FF00)>>8 == 226)

    就可以过滤出这种颜色的像素点,

    0xFFFFFF00代表着RGB为255,255,255,0
    0XF8EEE200代表着RGB为248,238,226,0

    16进制的颜色,0X后每2位代表着16进制的RGB值;
    如此之后我的图片变成了

    aaa.png
    bbb.png

    在此张图片的效果并不好是因为图片颜色相近并且RGB颜色都有细小的差别 不能整个进行扣图处理 但是相信对一部分图片还是有处理能力的,欢迎补充和拍砖

    相关文章

      网友评论

        本文标题:iOS开发图片RGB调整

        本文链接:https://www.haomeiwen.com/subject/nibydttx.html