zoukankan      html  css  js  c++  java
  • 替换图像的某种色值

    const  unsigned char RGBMAX = 255;
    #define EqualZero(a) ((a) == 0)
    
    void cvtRGBToHSI(CGFloat iR,CGFloat iG, CGFloat iB, unsigned char * rH, unsigned char * rS, unsigned char *rI)
    {
        /*
         当人观察一个彩色物体时,用色调、饱和度、亮度来描述物体的颜色。HSI〔Hue-Saturation-Intensity(Lightness),HSI或HSL〕颜色模型用H、S、I三参数描述颜色特性,其中H定义颜色的波长,称为色调;S表示颜色的深浅程度,称为饱和度;I表示强度或亮度。在HSI颜色模型的双六棱锥表示,I是强度轴,色调H的角度范围为[0,2π],其中,纯红色的角度为0,纯绿色的角度为2π/3,纯蓝色的角度为4π/3
         
         */
        const   float PI2 = 2*3.1415926;
        float r = (float)iR;
        float g = (float)iG;
        float b = (float)iB;
        float maxVal = MAX(MAX(r, g), b);
        float minVal = MIN(MIN(r, g), b);
        float   i = (r + g + b)/3;
        float   s = 0.0f;
        float   h = 0.0f;
        if(!EqualZero(i) && !EqualZero(maxVal -minVal))
        {
            float   diff  = 0.5f*(r-g + r-b);
            float   diff2 = (r-g)*(r-g) + (r-g)*(g-b);  //diff2 永远 > 0
            float   sita  = acos(diff/sqrt(diff2))/PI2; //角度,PI2为1
            h   = (g>=b) ? sita : (1.0f - sita);
            s   = 1.0f - minVal/i;
        }
        if  (h < 0.0f )       h += 1.0f;
        else if (h > 1.0f ) h -= 1.0f;
        *rH = (unsigned char)round(h*RGBMAX);    //range: 0 to 255;
        *rS = (unsigned char)round(s*RGBMAX);     //range: 0 to 255;
        *rI =  (unsigned char)round(i*RGBMAX);     //range:  0 to 255;
    }
    
    unsigned char subUnsignedChar(unsigned char a,unsigned char b)
    {
        return (a>b)?(a-b):(b-a);
    }
    
    -(BOOL)beSimilarColor:(UIColor*)color1 withColor:(UIColor*)color2 withDifference:(unsigned char)difference
    {
        CGFloat r1,r2,g1,g2,b1,b2,a1,a2;
        unsigned char h1,h2,s1,s2,i1,i2;
        [color1 getRed:&r1 green:&g1 blue:&b1 alpha:&a1];
        [color2 getRed:&r2 green:&g2 blue:&b2 alpha:&a2];
        cvtRGBToHSI(r1, g1, b1, &h1, &s1, &i1);
        cvtRGBToHSI(r2, g2, b2, &h2, &s2, &i2);
        unsigned char maxGap = difference;
        if (a1 == a2 && (subUnsignedChar(h1, h2) <= maxGap) && (subUnsignedChar(s1, s2) <= maxGap) && (subUnsignedChar(i1, i2) <= maxGap)) {
            return YES;
        }
        return NO;
    }
    
    #pragma mark 图片替换颜色
    
    -(UIImage*)videoPictureImageForReplaceColor:(UIColor*)color toColor:(UIColor*)otherColor withImage:(UIImage*)image withDifference:(unsigned char)difference
    {
        CVPixelBufferRef pixelBuffer = NULL;
        CGImageRef img = image.CGImage;
        size_t width = CGImageGetWidth(img);
        size_t height = CGImageGetHeight(img);
        CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, nil, &pixelBuffer);
        if (status != kCVReturnSuccess) {
            return NULL;
        }
        size_t rowBytes = CVPixelBufferGetBytesPerRow(pixelBuffer);
        CVPixelBufferLockBaseAddress(pixelBuffer, 0);
        void *data = CVPixelBufferGetBaseAddress(pixelBuffer);
        
        CGFloat r,g,b,a;
        [otherColor getRed:&r green:&g blue:&b alpha:&a];
        
        CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(data, width, height, 8, rowBytes, rgbColorSpace, (CGBitmapInfo) kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
        CGContextClearRect(context, CGRectMake(0, 0, width, height));
        CGContextDrawImage(context, CGRectMake(0, 0, width, height), img);
        
        unsigned char *colorPtr = (unsigned char *)data;
        
        for (size_t h = 0; h < height; h++) {
            for (size_t w = 0; w < width; w++) {
                
                if ([self beSimilarColor:[UIColor colorWithRed:colorPtr[0]/255.0f green:colorPtr[1]/255.0f blue:colorPtr[2]/255.0f alpha:colorPtr[3]/255.0f] withColor:color withDifference:difference]) {
                    //                printf("%d  %d  %d  %d
    ",colorPtr[0],colorPtr[1],colorPtr[2],colorPtr[3]);
                    
                    colorPtr[0] = round(r*255);
                    colorPtr[1] = round(g*255);
                    colorPtr[2] = round(b*255);
                    colorPtr[3] = round(a*255);
                }
                colorPtr += 4;
            }
        }
        CGImageRef imageRef = CGBitmapContextCreateImage (context);
        CGColorSpaceRelease(rgbColorSpace);
        CGContextRelease(context);
        CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
        UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
        //clean up
        CGImageRelease(imageRef);
        CVPixelBufferRelease(pixelBuffer);
        return returnImage;
    }
  • 相关阅读:
    RMAN备份脚本
    配置putty隧道登录远程window远程或远程数据库
    ssh登录报错:no common kex alg
    Solaris上修改进程能够打开的最大文件句柄数
    如何在V890上安装配置rsc(转)
    Oracle表或分区导出脚本
    检查日期合法性脚本(转)
    Solaris下常用的磁带操作命令
    如何从solaris操作系统上获取机器的sn号
    如何修复failed磁盘和"DISABLED RECOVER"状态的plex
  • 原文地址:https://www.cnblogs.com/yuxiaoyiyou/p/9831666.html
Copyright © 2011-2022 走看看