• UIImage图片处理


    #pragma mark -
    #pragma mark - 缩放处理
    
    + (UIImage *)scaleImage:(UIImage *)image withScale:(float)scale
    {
        UIGraphicsBeginImageContext(CGSizeMake(image.size.width * scale, image.size.height * scale));
        
        [image drawInRect:CGRectMake(0, 0, image.size.width * scale, image.size.height * scale)];
        UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
        
        UIGraphicsEndImageContext();
        
        return scaledImage;
    }
    
    + (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)size
    {
        UIGraphicsBeginImageContext(CGSizeMake(size.width, size.height));
        
        [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
        UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
        
        UIGraphicsEndImageContext();
        
        return scaledImage;
    }
    
    #pragma mark -
    #pragma mark - 马赛克处理
    
    static CGContextRef CreateRGBABitmapContext (CGImageRef inImage)
    {
        CGContextRef context = NULL;
        CGColorSpaceRef colorSpace;
        void *bitmapData; //内存空间的指针,该内存空间的大小等于图像使用RGB通道所占用的字节数。
        int bitmapByteCount;
        int bitmapBytesPerRow;
        
        size_t pixelsWide = CGImageGetWidth(inImage); //获取横向的像素点的个数
        size_t pixelsHigh = CGImageGetHeight(inImage);
        
        bitmapBytesPerRow    = (pixelsWide * 4); //每一行的像素点占用的字节数,每个像素点的ARGB四个通道各占8个bit(0-255)的空间
        bitmapByteCount    = (bitmapBytesPerRow * pixelsHigh); //计算整张图占用的字节数
        
        colorSpace = CGColorSpaceCreateDeviceRGB();//创建依赖于设备的RGB通道
        //分配足够容纳图片字节数的内存空间
        bitmapData = malloc( bitmapByteCount );
        //创建CoreGraphic的图形上下文,该上下文描述了bitmaData指向的内存空间需要绘制的图像的一些绘制参数
        context = CGBitmapContextCreate (bitmapData,
                                         pixelsWide,
                                         pixelsHigh,
                                         8,
                                         bitmapBytesPerRow,
                                         colorSpace,
                                         kCGImageAlphaPremultipliedLast);
        //Core Foundation中通过含有Create、Alloc的方法名字创建的指针,需要使用CFRelease()函数释放
        CGColorSpaceRelease( colorSpace );
        return context;
    }
    
    static unsigned char *RequestImagePixelData(UIImage *inImage)
    {
        CGImageRef img = [inImage CGImage];
        CGSize size = [inImage size];
        //使用上面的函数创建上下文
        CGContextRef cgctx = CreateRGBABitmapContext(img);
        
        CGRect rect = {{0,0},{size.width, size.height}};
        //将目标图像绘制到指定的上下文,实际为上下文内的bitmapData。
        CGContextDrawImage(cgctx, rect, img);
        unsigned char *data = CGBitmapContextGetData (cgctx);
        //释放上面的函数创建的上下文
        CGContextRelease(cgctx);
        return data;
    }
    
    + (UIImage *)mosaicImage:(UIImage *)image withLevel:(int)level
    {
        unsigned char *imgPixel = RequestImagePixelData(image);
        CGImageRef inImageRef = [image CGImage];
        GLuint width = CGImageGetWidth(inImageRef);
        GLuint height = CGImageGetHeight(inImageRef);
        unsigned char prev[4] = {0};
        int bytewidth = width*4;
        int i,j;
        int val = level;
        for(i=0;i<height;i++) {
            if (((i+1)%val) == 0) {
                memcpy(imgPixel+bytewidth*i, imgPixel+bytewidth*(i-1), bytewidth);
                continue;
            }
            for(j=0;j<width;j++) {
                if (((j+1)%val) == 1) {
                    memcpy(prev, imgPixel+bytewidth*i+j*4, 4);
                    continue;
                }
                memcpy(imgPixel+bytewidth*i+j*4, prev, 4);
            }
        }
        NSInteger dataLength = width*height* 4;
        
        //下面的代码创建要输出的图像的相关参数
        CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, imgPixel, dataLength, NULL);
        // prep the ingredients
        int bitsPerComponent = 8;
        int bitsPerPixel = 32;
        CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
        CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
        CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
        //创建要输出的图像
        CGImageRef imageRef = CGImageCreate(width, height,
                                            bitsPerComponent,
                                            bitsPerPixel,
                                            bytewidth,
                                            colorSpaceRef,
                                            bitmapInfo,
                                            provider,
                                            NULL, NO, renderingIntent);
        UIImage *mosaicImage = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation];
        CFRelease(imageRef);
        CGColorSpaceRelease(colorSpaceRef);
        CGDataProviderRelease(provider);
        return mosaicImage;
    }
    
    #define kBitsPerComponent (8)
    #define kBitsPerPixel (32)
    #define kPixelChannelCount (4)
    
    /*
     *转换成马赛克,level代表一个点转为多少level*level的正方形
     */
    + (UIImage *)transToMosaicImage:(UIImage*)orginImage blockLevel:(NSUInteger)level
    {
        //获取BitmapData
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGImageRef imgRef = orginImage.CGImage;
        CGFloat width = CGImageGetWidth(imgRef);
        CGFloat height = CGImageGetHeight(imgRef);
        CGContextRef context = CGBitmapContextCreate (nil,
                                                      width,
                                                      height,
                                                      kBitsPerComponent,        //每个颜色值8bit
                                                      width*kPixelChannelCount, //每一行的像素点占用的字节数,每个像素点的ARGB四个通道各占8个bit
                                                      colorSpace,
                                                      kCGImageAlphaPremultipliedLast);
        CGContextDrawImage(context, CGRectMake(0, 0, width, height), imgRef);
        unsigned char *bitmapData = CGBitmapContextGetData (context);
        
        //这里把BitmapData进行马赛克转换,就是用一个点的颜色填充一个level*level的正方形
        unsigned char pixel[kPixelChannelCount] = {0};
        NSUInteger index,preIndex;
        for (NSUInteger i = 0; i < height - 1 ; i++) {
            for (NSUInteger j = 0; j < width - 1; j++) {
                index = i * width + j;
                if (i % level == 0) {
                    if (j % level == 0) {
                        memcpy(pixel, bitmapData + kPixelChannelCount*index, kPixelChannelCount);
                    }else{
                        memcpy(bitmapData + kPixelChannelCount*index, pixel, kPixelChannelCount);
                    }
                } else {
                    preIndex = (i-1)*width +j;
                    memcpy(bitmapData + kPixelChannelCount*index, bitmapData + kPixelChannelCount*preIndex, kPixelChannelCount);
                }
            }
        }
        
        NSInteger dataLength = width*height* kPixelChannelCount;
        CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bitmapData, dataLength, NULL);
        //创建要输出的图像
        CGImageRef mosaicImageRef = CGImageCreate(width, height,
                                                  kBitsPerComponent,
                                                  kBitsPerPixel,
                                                  width*kPixelChannelCount ,
                                                  colorSpace,
                                                  kCGImageAlphaPremultipliedLast,
                                                  provider,
                                                  NULL, NO,
                                                  kCGRenderingIntentDefault);
        CGContextRef outputContext = CGBitmapContextCreate(nil,
                                                           width,
                                                           height,
                                                           kBitsPerComponent,
                                                           width*kPixelChannelCount,
                                                           colorSpace,
                                                           kCGImageAlphaPremultipliedLast);
        CGContextDrawImage(outputContext, CGRectMake(0.0f, 0.0f, width, height), mosaicImageRef);
        CGImageRef resultImageRef = CGBitmapContextCreateImage(outputContext);
        UIImage *resultImage = nil;
        if([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) {
    //        float scale = [[UIScreen mainScreen] scale];
    //        resultImage = [UIImage imageWithCGImage:resultImageRef scale:scale orientation:UIImageOrientationUp];
            resultImage = [UIImage imageWithCGImage:resultImageRef scale:orginImage.scale orientation:orginImage.imageOrientation];
        } else {
            resultImage = [UIImage imageWithCGImage:resultImageRef];
        }
        //释放
        if(resultImageRef){
            CFRelease(resultImageRef);
        }
        if(mosaicImageRef){
            CFRelease(mosaicImageRef);
        }
        if(colorSpace){
            CGColorSpaceRelease(colorSpace);
        }
        if(provider){
            CGDataProviderRelease(provider);
        }
        if(context){
            CGContextRelease(context);
        }
        if(outputContext){
            CGContextRelease(outputContext);
        }
    //    return [[resultImage retain] autorelease];
        return resultImage;
        
    }
  • 相关阅读:
    50 系统调用的实现
    49 进程调度预备开发(下)
    48 进程调度预备开发(上)
    47 多进程并行执行(下)
    IIC总线
    46 多进程并行执行(上)
    45 内核中的中断处理(下)
    解决错误/usr/bin/ld: cannot find -lz
    rsync只传输隐藏文件
    Firewall命令
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4947501.html
Copyright © 2020-2023  润新知