美图秀秀美化图片之【增强】模块界面与功能设计
本文从【增强】模块入手介绍一下界面设计和功能实现。所有功能都已实现,部分功能有待改善,我会在以后时间中步步改善。目前效果也很棒。有兴趣的可以在文章最后提供的下载链接中下载并运行。模拟器最好使用iphone6模拟器【增强】功能包含如下功能
1.亮度
2.对比度
3.色温
4.饱和度
5.高光
6.暗部
7.智能补光
涉及开发技巧
效果bar的实现
UISlider的使用
GPUImage的使用
一、自定义bar
点击一个效果按钮时,该按钮变为高亮状态,而前面的按钮自动恢复到正常状态
代码实现
#import <UIKit/UIKit.h> @class FWEffectBar, FWEffectBarItem; @protocol FWEffectBarDelegate <NSObject> - (void)effectBar:(FWEffectBar *)bar didSelectItemAtIndex:(NSInteger)index; @end @interface FWEffectBar : UIScrollView @property (nonatomic, assign) id<FWEffectBarDelegate> delegate; @property (nonatomic, copy) NSArray *items; @property (nonatomic, weak) FWEffectBarItem *selectedItem; @property UIEdgeInsets contentEdgeInsets; /** * Sets the height of tab bar. */ - (void)setHeight:(CGFloat)height; /** * Returns the minimum height of tab bar's items. */ - (CGFloat)minimumContentHeight; @end
// // FWEffectBar.m // FWMeituApp // // Created by ForrestWoo on 15-9-23. // Copyright (c) 2015年 ForrestWoo co,.ltd. All rights reserved. // #import "FWEffectBar.h" #import "FWEffectBarItem.h" @interface FWEffectBar () @property (nonatomic) CGFloat itemWidth; @end @implementation FWEffectBar - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { } return self; } - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { } return self; } - (id)init { return [self initWithFrame:CGRectZero]; } - (void)layoutSubviews { CGSize frameSize = self.frame.size; CGFloat minimumContentHeight = [self minimumContentHeight]; [self setItemWidth:roundf((frameSize.width - [self contentEdgeInsets].left - [self contentEdgeInsets].right) / [[self items] count])]; NSInteger index = 0; // Layout items for (FWEffectBarItem *item in [self items]) { CGFloat itemHeight = [item itemHeight]; if (!itemHeight) { itemHeight = frameSize.height; } [item setFrame:CGRectMake(self.contentEdgeInsets.left + (index * self.itemWidth), roundf(frameSize.height - itemHeight) - self.contentEdgeInsets.top, self.itemWidth, itemHeight - self.contentEdgeInsets.bottom)]; [item setNeedsDisplay]; index++; } } #pragma mark - Configuration - (void)setItemWidth:(CGFloat)itemWidth { if (itemWidth > 0) { _itemWidth = itemWidth; } } - (void)setItems:(NSArray *)items { for (FWEffectBarItem *item in _items) { [item removeFromSuperview]; } _items = [items copy]; for (FWEffectBarItem *item in _items) { [item addTarget:self action:@selector(tabBarItemWasSelected:) forControlEvents:UIControlEventTouchDown]; [self addSubview:item]; } } - (void)setHeight:(CGFloat)height { [self setFrame:CGRectMake(CGRectGetMinX(self.frame), CGRectGetMinY(self.frame), CGRectGetWidth(self.frame), height)]; } - (CGFloat)minimumContentHeight { CGFloat minimumTabBarContentHeight = CGRectGetHeight([self frame]); for (FWEffectBarItem *item in [self items]) { CGFloat itemHeight = [item itemHeight]; if (itemHeight && (itemHeight < minimumTabBarContentHeight)) { minimumTabBarContentHeight = itemHeight; } } return minimumTabBarContentHeight; } #pragma mark - Item selection - (void)tabBarItemWasSelected:(id)sender { [self setSelectedItem:sender]; if ([[self delegate] respondsToSelector:@selector(effectBar:didSelectItemAtIndex:)]) { NSInteger index = [self.items indexOfObject:self.selectedItem]; [[self delegate] effectBar:self didSelectItemAtIndex:index]; } } - (void)setSelectedItem:(FWEffectBarItem *)selectedItem { if (selectedItem == _selectedItem) { return; } [_selectedItem setSelected:NO]; _selectedItem = selectedItem; [_selectedItem setSelected:YES]; } @end
我定义了一个FWEffectBarDelegate的协议,当点击bar中按钮时,将触发- (void)effectBar:(FWEffectBar *)bar didSelectItemAtIndex:(NSInteger)index,我们可以在FWEffectBar的代理中实现当我们点击按钮时要做的事情。
items属性是该bar所包含的所有子项(FWEffectBarItem)。
FWEffectBarItem是包含在bar中的按钮,图像文字竖着排列,当点击它时将呈现高亮状态。
// // FWEffectBarItem.h // FWMeituApp // // Created by ForrestWoo on 15-9-23. // Copyright (c) 2015年 ForrestWoo co,.ltd. All rights reserved. // #import <UIKit/UIKit.h> @interface FWEffectBarItem : UIControl /** * itemHeight is an optional property. When set it is used instead of tabBar's height. */ @property CGFloat itemHeight; #pragma mark - Title configuration /** * The title displayed by the tab bar item. */ @property (nonatomic, copy) NSString *title; /** * The offset for the rectangle around the tab bar item's title. */ @property (nonatomic) UIOffset titlePositionAdjustment; /** * For title's text attributes see * https://developer.apple.com/library/ios/documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference.html */ /** * The title attributes dictionary used for tab bar item's unselected state. */ @property (copy) NSDictionary *unselectedTitleAttributes; /** * The title attributes dictionary used for tab bar item's selected state. */ @property (copy) NSDictionary *selectedTitleAttributes; #pragma mark - Image configuration /** * The offset for the rectangle around the tab bar item's image. */ @property (nonatomic) UIOffset imagePositionAdjustment; /** * The image used for tab bar item's selected state. */ - (UIImage *)finishedSelectedImage; /** * The image used for tab bar item's unselected state. */ - (UIImage *)finishedUnselectedImage; /** * Sets the tab bar item's selected and unselected images. */ - (void)setFinishedSelectedImage:(UIImage *)selectedImage withFinishedUnselectedImage:(UIImage *)unselectedImage; #pragma mark - Background configuration /** * The background image used for tab bar item's selected state. */ - (UIImage *)backgroundSelectedImage; /** * The background image used for tab bar item's unselected state. */ - (UIImage *)backgroundUnselectedImage; /** * Sets the tab bar item's selected and unselected background images. */ - (void)setBackgroundSelectedImage:(UIImage *)selectedImage withUnselectedImage:(UIImage *)unselectedImage; @end
// // FWEffectBarItem.m // FWMeituApp // // Created by ForrestWoo on 15-9-23. // Copyright (c) 2015年 ForrestWoo co,.ltd. All rights reserved. // #import "FWEffectBarItem.h" @interface FWEffectBarItem () { NSString *_title; UIOffset _imagePositionAdjustment; NSDictionary *_unselectedTitleAttributes; NSDictionary *_selectedTitleAttributes; } @property UIImage *unselectedBackgroundImage; @property UIImage *selectedBackgroundImage; @property UIImage *unselectedImage; @property UIImage *selectedImage; @end @implementation FWEffectBarItem - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { [self commonInitialization]; } return self; } - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { [self commonInitialization]; } return self; } - (id)init { return [self initWithFrame:CGRectZero]; } - (void)commonInitialization { // Setup defaults [self setBackgroundColor:[UIColor clearColor]]; _title = @""; _titlePositionAdjustment = UIOffsetZero; if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { _unselectedTitleAttributes = @{ NSFontAttributeName: [UIFont systemFontOfSize:12], NSForegroundColorAttributeName: [UIColor whiteColor], }; } else { #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 _unselectedTitleAttributes = @{ UITextAttributeFont: [UIFont systemFontOfSize:12], UITextAttributeTextColor: [UIColor blackColor], }; #endif } _selectedTitleAttributes = [_unselectedTitleAttributes copy]; } - (void)drawRect:(CGRect)rect { CGSize frameSize = self.frame.size; CGSize imageSize = CGSizeZero; CGSize titleSize = CGSizeZero; NSDictionary *titleAttributes = nil; UIImage *backgroundImage = nil; UIImage *image = nil; CGFloat imageStartingY = 0.0f; if ([self isSelected]) { image = [self selectedImage]; backgroundImage = [self selectedBackgroundImage]; titleAttributes = [self selectedTitleAttributes]; if (!titleAttributes) { titleAttributes = [self unselectedTitleAttributes]; } } else { image = [self unselectedImage]; backgroundImage = [self unselectedBackgroundImage]; titleAttributes = [self unselectedTitleAttributes]; } imageSize = [image size]; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); [backgroundImage drawInRect:self.bounds]; // Draw image and title if (![_title length]) { [image drawInRect:CGRectMake(roundf(frameSize.width / 2 - imageSize.width / 2) + _imagePositionAdjustment.horizontal, roundf(frameSize.height / 2 - imageSize.height / 2) + _imagePositionAdjustment.vertical, imageSize.width, imageSize.height)]; } else { if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { CGSize ts = CGSizeMake(frameSize.width, 20); titleSize = [_title boundingRectWithSize:ts options:NSStringDrawingUsesLineFragmentOrigin attributes:titleAttributes context:nil].size; imageStartingY = roundf((frameSize.height - imageSize.height - titleSize.height) / 2); CGRect frame = CGRectMake(roundf(frameSize.width / 2 - imageSize.width / 2) + _imagePositionAdjustment.horizontal, imageStartingY + _imagePositionAdjustment.vertical, imageSize.width, imageSize.height); [image drawInRect:frame]; // NSLog(@"image frame:%@,%f,%f", NSStringFromCGRect(CGRectMake(roundf(frameSize.width / 2 - imageSize.width / 2) + // _imagePositionAdjustment.horizontal, // imageStartingY + _imagePositionAdjustment.vertical, // imageSize.width, imageSize.height)),imageStartingY,_imagePositionAdjustment.vertical); CGContextSetFillColorWithColor(context, [titleAttributes[NSForegroundColorAttributeName] CGColor]); CGRect frame1 = CGRectMake(roundf(frameSize.width / 2 - titleSize.width / 2) + _titlePositionAdjustment.horizontal, imageStartingY + imageSize.height + _titlePositionAdjustment.vertical, titleSize.width, titleSize.height); // NSLog(@"text frame:%@", NSStringFromCGRect(frame1)); // NSLog(@"self frame:%@", NSStringFromCGRect(rect)); [_title drawInRect:frame1 withAttributes:titleAttributes]; } else { #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 titleSize = [_title sizeWithFont:titleAttributes[UITextAttributeFont] constrainedToSize:CGSizeMake(frameSize.width, 20)]; UIOffset titleShadowOffset = [titleAttributes[UITextAttributeTextShadowOffset] UIOffsetValue]; imageStartingY = roundf((frameSize.height - imageSize.height - titleSize.height) / 2); [image drawInRect:CGRectMake(roundf(frameSize.width / 2 - imageSize.width / 2) + _imagePositionAdjustment.horizontal, imageStartingY + _imagePositionAdjustment.vertical, imageSize.width, imageSize.height)]; CGContextSetFillColorWithColor(context, [titleAttributes[UITextAttributeTextColor] CGColor]); UIColor *shadowColor = titleAttributes[UITextAttributeTextShadowColor]; if (shadowColor) { CGContextSetShadowWithColor(context, CGSizeMake(titleShadowOffset.horizontal, titleShadowOffset.vertical), 1.0, [shadowColor CGColor]); } [_title drawInRect:CGRectMake(roundf(frameSize.width / 2 - titleSize.width / 2) + _titlePositionAdjustment.horizontal, imageStartingY + imageSize.height + _titlePositionAdjustment.vertical, titleSize.width, titleSize.height) withFont:titleAttributes[UITextAttributeFont] lineBreakMode:NSLineBreakByTruncatingTail]; #endif } } CGContextRestoreGState(context); } - (UIImage *)finishedSelectedImage { return [self selectedImage]; } - (UIImage *)finishedUnselectedImage { return [self unselectedImage]; } - (void)setFinishedSelectedImage:(UIImage *)selectedImage withFinishedUnselectedImage:(UIImage *)unselectedImage { if (selectedImage && (selectedImage != [self selectedImage])) { [self setSelectedImage:selectedImage]; } if (unselectedImage && (unselectedImage != [self unselectedImage])) { [self setUnselectedImage:unselectedImage]; } } - (UIImage *)backgroundSelectedImage { return [self selectedBackgroundImage]; } - (UIImage *)backgroundUnselectedImage { return [self unselectedBackgroundImage]; } - (void)setBackgroundSelectedImage:(UIImage *)selectedImage withUnselectedImage:(UIImage *)unselectedImage { if (selectedImage && (selectedImage != [self selectedBackgroundImage])) { [self setSelectedBackgroundImage:selectedImage]; } if (unselectedImage && (unselectedImage != [self unselectedBackgroundImage])) { [self setUnselectedBackgroundImage:unselectedImage]; } } @end
- (void)setFinishedSelectedImage:(UIImage *)selectedImage withFinishedUnselectedImage:(UIImage *)unselectedImage方法用来设置FWEffectBarItem的被选中和未选中时的图片
title属性用来设置FWEffectBarItem的文字。
二、UISlider的使用
UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(0, HEIGHT - 115 - 40, WIDTH, 40)]; subview.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]; [self.view addSubview:subview]; self.slider = [[FWSlider alloc] initWithFrame:CGRectZero];
self.slider.minimumValue = -100; self.slider.maximumValue = 100; self.slider.value = 0; self.slider.frame = CGRectMake(WIDTH / 2 - 100, 10, 200, 20); [self.slider addTarget:self action:@selector(updateValue:) forControlEvents:UIControlEventTouchUpInside]; [self.slider addTarget:self action:@selector(updateTipView:) forControlEvents:UIControlEventValueChanged]; [self.slider setThumbImage:[UIImage imageNamed:@"icon_slider_thumb"] forState:UIControlStateNormal]; [subview addSubview:self.slider];
setThumbImage用来设置滑块,该slider没有完全实现,当我们滑动的时候,没有显示当前值,有待改善
四、FWBeautyProcessType枚举的定义
typedef NS_ENUM(NSInteger, FWBeautyProcessType) { //智能优化 FWBeautyProcessTypeAutoBeauty, //编辑 FWBeautyProcessTypeEdit, //增强 FWBeautyProcessTypeColorList, //特效 FWBeautyProcessTypeFilter, //边框 FWBeautyProcessTypeBolder, //魔幻笔 FWBeautyProcessTypeMagicPen, //马赛克 FWBeautyProcessTypeMosaic, //文字 FWBeautyProcessTypeText, //背景虚化 FWBeautyProcessTypeBlur };
该枚举定义了【美化图片】下的所有功能模块,用于识别到底是哪种模块,不同模块相应的界面是不同的,请看下面代码
- (void)setupImageView { if (self.type == FWBeautyProcessTypeAutoBeauty || self.type == FWBeautyProcessTypeColorList || self.type == FWBeautyProcessTypeEdit) { //105 = 设备高 - 关闭按钮高度 - 3段间距:30 - bar高度:55 - 的结果 self.imageView.frame = CGRectMake(0, 0, WIDTH, HEIGHT - 115); } self.imageView.contentMode = UIViewContentModeScaleAspectFit; [self.view addSubview:self.imageView]; } //配置单选项卡 - (void)setupBar { self.styleBar = [[FWEffectBar alloc] init]; NSDictionary *autoDict = nil; if (self.type == FWBeautyProcessTypeAutoBeauty || self.type == FWBeautyProcessTypeColorList) { self.styleBar.frame = CGRectMake(0,HEIGHT - 105, WIDTH, 55); if (self.type == FWBeautyProcessTypeAutoBeauty ) autoDict = [[FWCommonTools getPlistDictionaryForButton] objectForKey:@"AutoBeauty"]; else autoDict = [[FWCommonTools getPlistDictionaryForButton] objectForKey:@"ColorValue"]; } else if (self.type == FWBeautyProcessTypeEdit) { self.styleBar.frame = CGRectMake(100, HEIGHT - 55, 160, 55); autoDict = [[FWCommonTools getPlistDictionaryForButton] objectForKey:@"Edit"]; } NSArray *normalImageArr = [autoDict objectForKey:@"normalImages"]; NSArray *hightlightedImageArr = [autoDict objectForKey:@"HighlightedImages"]; NSArray *textArr = [autoDict objectForKey:@"Texts"]; NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:0]; for (int i = 0; i < [textArr count]; i++) { FWEffectBarItem *item = [[FWEffectBarItem alloc] initWithFrame:CGRectZero]; [item setFinishedSelectedImage:[UIImage imageNamed:[hightlightedImageArr objectAtIndex:i]] withFinishedUnselectedImage:[UIImage imageNamed:[normalImageArr objectAtIndex:i]] ]; item.title = [textArr objectAtIndex:i]; [arr addObject:item]; } self.styleBar.items = arr; self.styleBar.delegate = self; [self.styleBar setSelectedItem:[self.styleBar.items objectAtIndex:0]]; [self.view addSubview:self.styleBar]; [self effectBar:self.styleBar didSelectItemAtIndex:0]; } - (void)setupSliderForColorList { UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(0, HEIGHT - 115 - 40, WIDTH, 40)]; subview.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]; [self.view addSubview:subview]; self.slider = [[FWSlider alloc] initWithFrame:CGRectZero]; self.slider.minimumValue = -100; self.slider.maximumValue = 100; self.slider.value = 0; self.slider.frame = CGRectMake(WIDTH / 2 - 100, 10, 200, 20); [self.slider addTarget:self action:@selector(updateValue:) forControlEvents:UIControlEventTouchUpInside]; [self.slider addTarget:self action:@selector(updateTipView:) forControlEvents:UIControlEventValueChanged]; [self.slider setThumbImage:[UIImage imageNamed:@"icon_slider_thumb"] forState:UIControlStateNormal]; [subview addSubview:self.slider]; self.slider.tipView.currentValueLabel.text = [NSString stringWithFormat:@"%f",self.slider.value]; }
不同页面的方法
- (void)displayAutoBeautyPage { [self setupImageView]; [self setupBar]; } - (void)displayColorListPage { [self setupImageView]; [self setupBar]; [self setupSliderForColorList]; } - (void)displayEditPage { [self setupImageView]; [self setupBar]; [self setupButtons]; }
if ([text isEqualToString:@"智能优化"]) { FWFunctionViewController *vc = [[FWFunctionViewController alloc] initWithImage:self.image type:FWBeautyProcessTypeAutoBeauty]; [self presentViewController:vc animated:YES completion:^{ }]; [vc displayAutoBeautyPage]; } else if ([text isEqualToString:@"增强"]) { FWFunctionViewController *vc = [[FWFunctionViewController alloc] initWithImage:self.image type:FWBeautyProcessTypeColorList]; [self presentViewController:vc animated:YES completion:^{ }]; [vc displayColorListPage]; } else if ([text isEqualToString:@"编辑"]) { FWFunctionViewController *vc = [[FWFunctionViewController alloc] initWithImage:self.image type:FWBeautyProcessTypeEdit]; [self presentViewController:vc animated:YES completion:^{ }]; [vc displayEditPage]; // CGRect frame1 = CGRectMake(87.5, 550, 200, 20); // [vc setupSliderWithFrame:frame1]; }e
五、功能实现
1.亮度的实现
+ (UIImage *)changeValueForBrightnessFilter:(float)value image:(UIImage *)image; { GPUImageBrightnessFilter *filter = [[GPUImageBrightnessFilter alloc] init]; filter.brightness = value; [filter forceProcessingAtSize:image.size]; GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image]; [pic addTarget:filter]; [pic processImage]; [filter useNextFrameForImageCapture]; return [filter imageFromCurrentFramebuffer]; }
该功能使用了GPUImage库中的GPUImageBrightnessFilter滤镜,具体介绍请参考GPUImage简单滤镜使用(一)
2.对比度的实现
GPUImageContrastFilter *filter = [[GPUImageContrastFilter alloc] init]; filter.contrast = value; [filter forceProcessingAtSize:image.size]; GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image]; [pic addTarget:filter]; [pic processImage]; [filter useNextFrameForImageCapture]; return [filter imageFromCurrentFramebuffer];
该功能使用了GPUImage库中的GPUImageContrastFilter滤镜,具体介绍请参考GPUImage简单滤镜使用(二)
3.色温的实现
+ (UIImage *)changeValueForWhiteBalanceFilter:(float)value image:(UIImage *)image { GPUImageWhiteBalanceFilter *filter = [[GPUImageWhiteBalanceFilter alloc] init]; filter.temperature = value; filter.tint = 0.0; [filter forceProcessingAtSize:image.size]; GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image]; [pic addTarget:filter]; [pic processImage]; [filter useNextFrameForImageCapture]; return [filter imageFromCurrentFramebuffer]; }
该功能使用了GPUImage库中的GPUImageWhiteBalanceFilter滤镜。
4.饱和度的实现
+ (UIImage *)changeValueForSaturationFilter:(float)value image:(UIImage *)image; { GPUImageSaturationFilter *filter = [[GPUImageSaturationFilter alloc] init]; filter.saturation = value; [filter forceProcessingAtSize:image.size]; GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image]; [pic addTarget:filter]; [pic processImage]; [filter useNextFrameForImageCapture]; return [filter imageFromCurrentFramebuffer]; }
该功能使用了GPUImage库中的GPUImageSaturationFilter滤镜。
5.高光和暗部的实现
+ (UIImage *)changeValueForHightlightFilter:(float)value image:(UIImage *)image; { GPUImageHighlightShadowFilter *filter = [[GPUImageHighlightShadowFilter alloc] init]; filter.highlights = value; filter.shadows = 0.0; [filter forceProcessingAtSize:image.size]; GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image]; [pic addTarget:filter]; [pic processImage]; [filter useNextFrameForImageCapture]; return [filter imageFromCurrentFramebuffer]; }
+ (UIImage *)changeValueForLowlightFilter:(float)value image:(UIImage *)image { GPUImageHighlightShadowFilter *filter = [[GPUImageHighlightShadowFilter alloc] init]; filter.highlights = 1.0; filter.shadows = value; [filter forceProcessingAtSize:image.size]; GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image]; [pic addTarget:filter]; [pic processImage]; [filter useNextFrameForImageCapture]; return [filter imageFromCurrentFramebuffer]; }
该功能使用了GPUImage库中的GPUImageHighlightShadowFilter滤镜。
6.智能补光的实现
+ (UIImage *)changeValueForExposureFilter:(float)value image:(UIImage *)image { GPUImageExposureFilter *filter = [[GPUImageExposureFilter alloc] init]; filter.exposure = value; [filter forceProcessingAtSize:image.size]; GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image]; [pic addTarget:filter]; [pic processImage]; [filter useNextFrameForImageCapture]; return [filter imageFromCurrentFramebuffer]; }
该功能使用了GPUImage库中的GPUImageExposureFilter滤镜。
我将会在以后的时间里添加几篇介绍GPUImage库中的剩余滤镜,慢慢来学习opengl es.加油,我的宝贝~上下眼皮开始打架了,睡觉喽!咦,最后附几张效果图吧
原图 亮度较暗 对比度较高
色温较冷 饱和度较高 高光
智能补光