mac tga转jpg

news/2024/12/29 15:34:32/

本文转自http://blog.codingmylife.com/?p=57,非常感谢原作者的分享

 

 

Core Image 学习笔记 - 为照片加边框和EXIF信息。

12,073 views, Cocoa, by Allen Dang.

最近迷上了摄影,拍了很多照片之后就想上传跟大家分享。到色影无忌和几个摄影论坛上一看,发现很多人的照片都有不错的边框、水印和拍摄信息(相机类型、光圈、快门、拍摄日期等等….)。
因为用的是Mac,找了很久,没有发现…(为什么每次写东西都是这个理由?)
好吧,废话少说,先把要做的事情分类。

1.调整图片大小,毕竟放到网上的图片不需要原图那么大。
————————————————–
以下是学习了Core Image之后的一点点实践。

NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
[image setScalesWhenResized:YES];
[image setSize:NSMakeSize(1000.0, [image size].height * (1000.0/[image size].width))];

这个方法确实可以调整大小了,但是缩小的图片质量非常差。花了很多时间仔细看文档,最后发现,Core Image其实就是对于Quartz 2D的包装,所有的绘图操作其实都值对于当前的NSGraphicsContext起作用,NSGraphicsContext本身有很多属性用来控制当前绘图的各方面。
而如果只是使用默认设置的话,绘图质量默认是最低。这里我们需要手动设置成高质量。
添加以下两行到代码开头:

//质量设置成高
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
//打开反锯齿
[[NSGraphicsContext currentContext] setShouldAntialias:YES];


2.画边框。
——–
一开始遇到的问题是,默认的NSGraphicsContext是当前窗体、View等等,我需要把它设置成我需要绘制的目标图片。出乎意料的简单。

NSImage *canvas = [[NSImage alloc] initWithSize:canvasSize];
[canvas lockFocus];
//Draw things here.
[canvas unlockFocus];

使用NSImage的lockFocus方法可以把NSGraphicsContext设置到它身上,相应的unlockFocus会还原NSGraphicsContext。

好了,现在就简单了,画边框了。

int border = 56;
NSRect rect = NSMakeRect(border/2, border/2, canvasSize.width - border, canvasSize.height - border);
[originImage drawInRect:rect
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0];
border -= 6;
[[NSColor whiteColor] set];
NSRect whiteBorderRect = NSMakeRect(border/2, border/2,
canvasSize.width - border, canvasSize.height - border);
NSBezierPath *whiteBorder = [NSBezierPath bezierPathWithRect:whiteBorderRect];
[whiteBorder setLineJoinStyle:NSRoundLineJoinStyle];
[whiteBorder setLineWidth:2];
[whiteBorder stroke];

这样就出现了一个白边框。

3.读取照片里面的EXIF信息,然后写到图片上。
—————————————
我原先只是知道一些C的库,但是这种功能Cocoa肯定是提供了的,但是我翻边了NS开头的绘图类,就是找不到,好吧,最后发现原来这部分需要直接调用Quartz 2D的函数了。

NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
NSDictionary *metaData = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
NSDictionary *exifData = [metaData objectForKey:@"{Exif}"];
NSDictionary *tiffData = [metaData objectForKey:@"{TIFF}"];

Exif字典里面有所有的拍摄参数,TIFF字典里面有相机型号。

***这里有个要注意的地方,CGImageSourceRef是需要手动释放的!***
我在后期调试程序的时候发现有内存泄露,找了很久才发现这里。

需要在使用完毕之后使用 CFRelease() 释放。代码修改之后是这样的

NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
NSDictionary *metaData = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
NSDictionary *exifData = [metaData objectForKey:@"{Exif}"];
NSDictionary *tiffData = [metaData objectForKey:@"{TIFF}"];
//读取想要的信息
[metaData release];
CFRelease(source);

好了,现在安全了。

4. 最后一项任务就是把加上边框和拍摄信息的图片保存到文件了。
——————————————————–
一开始我直接把 NSImage 的 TIFFRepresentation 直接写入文件了,最后发现文件体积太大,完全不像是jpg压缩过的样子,后来有是一番研究,找到了以下实现:

NSData *imageData = [image TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.9] forKey:NSImageCompressionFactor];
imageData = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];
[imageData writeToFile:path atomically:YES];

下面就是最后实现的效果图

temp.jpg


http://www.ppmy.cn/news/638812.html

相关文章

NeHe OpenGL第三十三课:TGA文件

NeHe OpenGL第三十三课:TGA文件 加载压缩和未压缩的TGA文件: 在这一课里,你将学会如何加载压缩和为压缩的TGA文件,由于它使用RLE压缩,所以非常的简单,你能很快地熟悉它的。 我见过很多人在游戏开发论坛或其它地方询问…

【鲁棒优化、机会约束】不确定风功率接入下电 - 气互联系统的协同经济调度(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

前端跨域解决方案及实践

什么是跨域 在Web开发中,跨域是指在浏览器中,一个网页的脚本试图访问另一个网页的资源时,由于浏览器的同源策略限制,请求会被拒绝。同源策略要求两个网页的协议、域名和端口号必须完全一致,否则就会出现跨域问题。 跨…

蓝丝雨第十四季商业实战系列(全民奇迹中控台实战)

蓝丝雨第十四季商业实战系列(全民奇迹中控台实战) 本套教程是以手游全民奇迹进行实战讲解,结合猩猩助手模拟器和大漠插件,形成一个中控台操作的脚本模板,方便新学员学习和使用。根据我们多年的脚本培训经验,我们打造了一系列优质的…

好嗨游戏:TapTap9.9分,《鸡你太美》这到底是什么魔鬼游戏?

要说最近最火的全民梗,一定是“鸡你太美”啦。火爆程度相比去年的大碗宽面绝对有过之而无不及,甚至连凡凡本人,也趁机发行了一首《大碗宽面》蹭了一波热度,借机用自黑的方式赢回了一些好感。 在如今全民作梗娱乐的时代&#xff0…

利用JavaScript实现京东自动叠蛋糕+淘宝自动领喵币,叠列车+618全民购物

京东自动叠蛋糕|淘宝自动领喵币&#xff0c;叠列车|618全民购物|JavaScript 行环境 安卓 JavaScript运行软件 Auto.js "ui"; var color "#009688"; main(); function main() {ui.layout(<drawer id"drawer"><vertical><appbar&g…

AI换脸引发全民恐慌,用对方向却能推动行业变革

这个周末AI换脸应用“ZAO”刷爆了朋友圈&#xff0c;并迅速登上微博热搜榜。好景不长&#xff0c;不到1天时间&#xff0c;就被微信屏蔽了分享链接&#xff0c;原因是较多用户投诉。舆论从开始的清一色“好玩”“有新意”&#xff0c;迅速转变为“不安全”“泄露隐私”“可怕”…

国民智能音箱品牌发展史:从春晚到跨年的全民普及

文|曾响铃 来源|科技向令说&#xff08;xiangling0815&#xff09; 智能音箱在国内刚刚兴起时&#xff0c;可能很少有人会想到&#xff0c;有一天它能作为一款成熟、独立的智能终端产品&#xff0c;以罕见的阵仗同时出现在几个全国性的跨年晚会上。 当百度小度以各种方式现…