//
//  UIImage+Helper.m
//  CXA
//
//  Created by Xummer on 14-3-3.
//  Copyright (c) 2014年 Xummer. All rights reserved.
//

#import "UIImage+Helper.h"

@implementation UIImage (Helper)

// if newImage's width or heigth < 1, image will be cliped
+ (UIImage *)getThumbnailImage:(UIImage *)image withMaxLen:(CGFloat)maxLen
{
    
    CGFloat imageMaxLen, imageMinLen;
    BOOL widthIsLarger = image.size.width > image.size.height;
    if (widthIsLarger) {
        imageMaxLen = image.size.width;
        imageMinLen = image.size.height;
    }
    else {
        imageMaxLen = image.size.height;
        imageMinLen = image.size.width;
    }
    
    if (imageMaxLen > maxLen) {
        CGFloat scaleFloat = maxLen/imageMaxLen;
        
        CGFloat newImgMinL = imageMinLen * scaleFloat;
        
        CGSize size;
        if (newImgMinL < 1) {
            scaleFloat = 1/imageMinLen;
            if (widthIsLarger) {
                size = CGSizeMake(maxLen, image.size.height * scaleFloat);
            }
            else {
                size = CGSizeMake(image.size.width * scaleFloat, maxLen);
            }
            
        }
        else {
            size = CGSizeMake(image.size.width * scaleFloat,
                              image.size.height * scaleFloat);
        }
        
        UIGraphicsBeginImageContext(size);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGAffineTransform transform = CGAffineTransformIdentity;
        
        transform = CGAffineTransformScale(transform, scaleFloat, scaleFloat);
        CGContextConcatCTM(context, transform);
        
        // Draw the image into the transformed context and return the image
        [image drawAtPoint:CGPointMake(0.0f, 0.0f)];
        UIImage *newimg = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        return newimg;
    }
    else{
        return image;
    }
}

- (UIImage *)thumbnailWithMaxLen:(CGFloat)maxLen {
    return [[self class] getThumbnailImage:self withMaxLen:maxLen];
}

- (UIImage *)imageWithTintColor:(UIColor *)tintColor {
    return [self imageWithTintColor:tintColor blendMode:kCGBlendModeDestinationIn];
}

- (UIImage *)imageWithGradientTintColor:(UIColor *)tintColor {
    return [self imageWithTintColor:tintColor blendMode:kCGBlendModeOverlay];
}

- (UIImage *)imageWithTintColor:(UIColor *)tintColor blendMode:(CGBlendMode)blendMode
{
    //We want to keep alpha, set opaque to NO; Use 0.0f for scale to use the scale factor of the device’s main screen.
    UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
    [tintColor setFill];
    CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
    UIRectFill(bounds);
    
    //Draw the tinted image in context
    [self drawInRect:bounds blendMode:blendMode alpha:1.0f];
    
    if (blendMode != kCGBlendModeDestinationIn) {
        [self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:1.0f];
    }
    
    UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return tintedImage;
}


@end

@implementation UIImage (Color)

typedef enum {
    ALPHA = 0,
    BLUE = 1,
    GREEN = 2,
    RED = 3
} PIXELS;

+ (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f,0.0f,1.0f,1.0f);
    return [[self class] imageWithColor:color andRect:rect];
}

+ (UIImage *)imageWithColor:(UIColor *)color andRect:(CGRect)rect {
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context =UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context,[color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *image =UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

+ (UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize)size {
    return [[self class] imageWithColor:color andRect:(CGRect){
        .origin = CGPointZero,
        .size = size
    }];
}

- (UIImage *)greyScaleImage {
    CGSize size = [self size];
    int width = size.width;
    int height = size.height;
    
    // the pixels will be painted to this array
    uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));
    
    // clear the pixels so any transparency is preserved
    memset(pixels, 0, width * height * sizeof(uint32_t));
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    
    // create a context with RGBA pixels
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,
                                                 kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
    
    // paint the bitmap to our context which will fill in the pixels array
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), [self CGImage]);
    
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x];
            
            // convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
            uint32_t gray = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];
            
            // set the pixels to gray
            rgbaPixel[RED] = gray;
            rgbaPixel[GREEN] = gray;
            rgbaPixel[BLUE] = gray;
        }
    }
    
    // create a new CGImageRef from our context with the modified pixels
    CGImageRef image = CGBitmapContextCreateImage(context);
    
    // we're done with the context, color space, and pixels
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(pixels);
    
    // make a new UIImage to return
    UIImage *resultUIImage = [UIImage imageWithCGImage:image];
    
    // we're done with image now too
    CGImageRelease(image);
    
    return resultUIImage;
}

- (NSData *)scaledToSpaceMaxSize:(NSInteger)kb {
    //压缩到100kb以内
    CGFloat compression = 0.5f;
    CGFloat maxCompression = 0.1f;
    NSUInteger maxlength = kb * 1024;
    NSData *imgData = UIImageJPEGRepresentation(self, compression);
    CLog(@"处理之前的大小--->%lukB",(unsigned long)imgData.length/1024);
    while ([imgData length] > maxlength && compression > maxCompression) {
        compression -= 0.1;
        imgData = UIImageJPEGRepresentation(self, compression);
    }
    CLog(@"处理之后的大小--->%lukB",(unsigned long)imgData.length/1024);
    return imgData;
    
}

- (UIImage *)scaledToSize:(CGSize)newSize {
    UIGraphicsBeginImageContextWithOptions(newSize, YES, 0);
    [self drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}

- (UIImage *)scaledToWidth:(NSInteger)newWidth {
    CLog(@"旧尺寸%@", NSStringFromCGSize(self.size));
    CGSize newSize = CGSizeMake(newWidth, newWidth / self.size.width * self.size.height);
    UIGraphicsBeginImageContextWithOptions(newSize, YES, 0);
    [self drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CLog(@"新尺寸%@", NSStringFromCGSize(scaledImage.size));

    return scaledImage;
}
-(NSData *)compressWithMaxLength:(NSUInteger)maxLength{
    CGFloat compression = 1;
    NSData *data = UIImageJPEGRepresentation(self, compression);
    if (data.length < maxLength) return data;
    
    CGFloat max = 1;
    CGFloat min = 0;
    for (int i = 0; i < 6; ++i) {
        compression = (max + min) / 2;
        data = UIImageJPEGRepresentation(self, compression);
        if (data.length < maxLength * 0.9) {
            min = compression;
        } else if (data.length > maxLength) {
            max = compression;
        } else {
            break;
        }
    }
    if (data.length < maxLength) return data;
    UIImage *resultImage = [UIImage imageWithData:data];
    NSUInteger lastDataLength = 0;
    while (data.length > maxLength && data.length != lastDataLength) {
        lastDataLength = data.length;
        CGFloat ratio = (CGFloat)maxLength / data.length;
        CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)),
                                 (NSUInteger)(resultImage.size.height * sqrtf(ratio)));
        UIGraphicsBeginImageContext(size);
        [resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
        resultImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        data = UIImageJPEGRepresentation(resultImage, compression);
    }
    return data;
}

@end
