这次我们要来学习如何为一张图片添加水印,为图片添加水印是现在很多社交软件都有实现的一个功能,我们在微博上面查看好友的图片的时候,图片的右下方经常附带有发表该微博的作者的名字,这就是我们今天要实现的效果。在示例的最后还会用到在学OC的时候学得NSData方法将处理后的位图保存为png或者jpg的图片文件。
有朋友也许会问,我们创建两个对象,一个是图片对象,一个是水印对象,水印对象的背景色设置为透明色,将两个对象进行重叠不就可以实现了水印的效果了嘛?
对,这样也可以达到目标,那是在图层上下文(layer graphics context)中实现的,这次我们来使用位图上下文(bitmap graphics context)来实现,顺便来了解一下位图上下文。什么是位图上下文呢?将绘制的东西输入到一张图片上,我们就称之为位图上下文。
PS:在UIView的drawRect获取的是图层上下文。
首先为项目添加两张图片,一张是主图,一张是水印图,然后为UIImage类创建分类,该分类实现的效果是合成一张水印图。
//创建分类:.h头文件
#import <UIKit/UIKit.h>
@interface UIImage (WaterMakerImage)
+ (instancetype)waterMakeImage:(NSString*)imageName underImage:(NSString*)underImageName;
@end
//.m源文件
#import "UIImage+WaterMakerImage.h"
@implementation UIImage (WaterMakerImage)
+ (instancetype)waterMakeImage:(NSString*)imageName underImage:(NSString*)underImageName
{
if(self){
}
//根据传进来的数据创建图片-主图
UIImage* underImage = [UIImage imageNamed:underImageName];
//创建位图上下文,在创建的时候已经是开启了位图上下文了。
/*
第一个参数是传入原始图片的的尺寸
第二个参数是alpha通道,yes是不透明,no是透明,选择no生成的图片会比较清晰
第三个参数是生成图片与原始图片的比例,这里如果传入0.0的话,表示默认是系统的比例
*/
UIGraphicsBeginImageContextWithOptions(underImage.size, NO, 0.0);
//绘制主图
UIScreen* screen = [UIScreen mainScreen];
float underImageW = underImage.size.width > screen.bounds.size.width ? screen.bounds.size.width:underImage.size.width;
float underImageH = underImageW/underImage.size.width*underImage.size.height;
[underImage drawInRect:CGRectMake(0, 20, underImageW, underImageH)];
//根据传进来的数据创建图片-水印
UIImage* waterMakeImage = [UIImage imageNamed:imageName];
//绘制水印
float waterMakeImageH = waterMakeImage.size.height>underImage.size.height*0.10?underImage.size.height*0.10:waterMakeImage.size.height;
float waterMakeImageW = waterMakeImage.size.width*(waterMakeImageH/waterMakeImage.size.height);
float waterMakeImageX = underImageW-waterMakeImageW;
float waterMakeImageY = underImageH-waterMakeImageH;
[waterMakeImage drawInRect:CGRectMake(waterMakeImageX, waterMakeImageY, waterMakeImageW, waterMakeImageH)];
// NSLog(@"%.2f,%.2f,%.2f,%.2f",waterMakeImageX,waterMakeImageY,waterMakeImageW,waterMakeImageH);
//用UIImage创建对象接受位图上下文绘制好的图片
UIImage* bitmapImage = UIGraphicsGetImageFromCurrentImageContext();
//结束位图编辑
UIGraphicsEndImageContext();
return bitmapImage;
}
@end
这样子,就已经创建好水印图片的实现了,现在只要在ViewController里面进行一些小设置就可以了。
- (void)viewDidLoad {
[super viewDidLoad];
UIImage* image = [UIImage waterMakeImage:@"xglog_wi" underImage:@"img"];
UIImageView* imageView = [[UIImageView alloc]initWithImage:image];
[self.view addSubview:imageView];
}
运行效果:
现在虽然可以看到生成水印图了,但是还没有做生成png格式图片的功能。现在就在Viewcontroller里面重写touch的一个方法,只要点击屏幕就会执行touch方法。
//该方法只要点击屏幕一次,就会把水印图按照程序所写的路径生成一张图片
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSData* PNGimage = UIImagePNGRepresentation(self.image);
//下面的这个方法是生成jpg图片的,后面的参数是图片的压缩质量
// NSData* pngImage = UIImageJPEGRepresentation(self.image, 0.7);
[PNGimage writeToFile:@"/Users/housn-k/Desktop/WaterMakeImage.png" atomically:YES];
}
效果图片:
博客代码