前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >用FreeSWITCH进行图像处理

用FreeSWITCH进行图像处理

作者头像
杜金房
发布2020-12-21 15:18:38
发布2020-12-21 15:18:38
90700
代码可运行
举报
运行总次数:0
代码可运行

在Mac上用Preview、Keynote、ImageMagick和FreeSWITCH进行图像处理

现在处理图片的软件这么多,你可能奇怪为什么需要用到FreeSWITCH处理图像。

是的,最流行也是最标准的图像处理工具当然是PhotoShop,PhotoShop如此流行,以至于它的缩写PS都成了图像处理的代名词。但是,PhotoShop唯一的缺点就是太贵,这些钱对于设计人员来说当然是值得花的,但对于广大程序员来说,它是个低频应用,可能一年中也用不了几次,就不合算。有时候实在需要,我也是使用GIMP凑合着用。GIMP是开源的,也能用,但说实话用起来确实不如PhotoShop顺手。

当然,作为一名程序员,希望寻找另外的工具的动机就是,是否有比较轻量级的工具,是否能自动批量处理等。

好了,言归正传,说说我为什么选了这么多工具来处理图像。

请听题:我的需求是,将我写的毛笔字底色处理成透明的,将黑色替换成需要的颜色,做在书的封面上。原始图像如下图。

当然这么折腾是有原因的,主要的原因是基本上所有好看的适合做封面的字体都是有版权的。

为了能在书中比较好的排版,在生成这幅图像时就使用了以下步骤和工具:

使用iPhone拍照,然后通过AirDrop传到Mac上,选中需要的文字,按⌘+K(或选菜单Tools --> Crop),保存或导出到PNG,就准备好了上面的图像。

查看图像的分辨率,这里用到了ImageMagick:

代码语言:javascript
代码运行次数:0
复制
identify wenji-1.png
wenji.png PNG 4032x1682 4032x1682+0+0 8-bit sRGB 5.11007MiB 0.000u 0:00.000

当然图像的分辨率比较高,我们根据需要降一下分辨率,以避免占用不必要的空间:

代码语言:javascript
代码运行次数:0
复制
convert wenji.png -resize 400x200 wenji-1.png

其中identityconvert都是ImageMagick里工具,后者可以改变图像的大小,生成一幅新的图像。『宽x高』是目标图像的大小,它默认会保持图像的比例,即如果原始图像比例与目标比例不一致的情况下,实际尺寸可能会比指定的值小,如:

代码语言:javascript
代码运行次数:0
复制
identify wenji-1.png
wenji-1.png PNG 400x167 400x167+0+0 8-bit sRGB 77381B 0.000u 0:00.000

接下来用以下命令就可以将底色变成透明的:

代码语言:javascript
代码运行次数:0
复制
convert wenji-1.png -fuzz 40% -transparent white wenji-2.png

代码语言:javascript
代码运行次数:0
复制
convert wenji-1.png -alpha set -channel RGBA -fuzz 20% -fill none +profile "*" +opaque "rgb(255,0,0)" wenji-2.png

下一步,尝试把文字变成红色的:

代码语言:javascript
代码运行次数:0
复制
convert wenji-2.png -alpha set -channel RGBA -fuzz 50% -fill red -draw "color 135,99 replace" wenji-3.png

找到文字上的一个点(方法有很多,我使用的是在Preview中打开图像,然后用矩形选择框从左上角选取区域,在移动鼠标的过程中就可以看到当前坐标,在此我们找到的点是(135,99)),然后以此为中心选取范围为50%的相似区域,替换成红色。图像如下。

但这样不完美:1)层次感没有了,2)太过粗糙。

虽然通过小心的调整参数可以做的好一点,但是还是达不到要求。

首先,ImageMagic在“抠图”(将底色变透明)时,由于背景明暗相差太大,需要很多次处理才能做得更好,但太多次数处理图像又会使图像质量变差,另外,我也不知道如何用ImageMagick处理颜色的层次。我们需要找新的工具。

完成这项任务的最好的工具当然是Keynote了。将原始图像插入Keynote,选右侧红色方框标的Instant Alpha按钮,然后用鼠标选中一个点,按下鼠标拖动就可以将相似的区域变为透明。超级好用。图中显示的是『文』字中间6%的情况。可以在不同的区域重复多次以便得到完美的效果。

处理完毕后,再复制图像,回到Preview中,新建一幅图像,内存中的内容将自动粘贴到图像中,保存为PNG就好了(记着保存时要选中(Alpha)以保证图像中有透明通道)。由于底色已经完全透明,我们可以看到复制后的图像已经比以前变小了。

代码语言:javascript
代码运行次数:0
复制
identify wenji-5.png
wenji-5.png PNG 256x143 256x143+0+0 8-bit sRGB 26574B 0.000u 0:00.000

下面的任务是要进行颜色替换,为此,我使用FreeSWITCH的库libfreeswitch写了一个程序,先看效果。

代码语言:javascript
代码运行次数:0
复制
./c wenji-5.png wenji-6.png

上代码。非常简单,连空行只有21行。

首先,第一行引入switch.h头文件。程序从main函数开始。在第5行,读入待处理的文件(命令行的第一个参数),在内容中存储的格式是ARGB,即具有Alpha通道,以保存图像的透明信息。

代码语言:javascript
代码运行次数:0
复制
 1	#include <switch.h>
 2
 3	int main(int argc, char **argv)
 4	{
 5		switch_image_t *img = switch_img_read_png(argv[1], SWITCH_IMG_FMT_ARGB);
 6		switch_assert(img);
 7
 8		int i, j;
 9

第10行,对图像从上到下逐行扫描(其中d_h为图像高度)。第11行,对当前行的每一个像素进行扫描。第12行,依次取每一个像素的颜色值。

其中img->planes[0]为图像的起始地址,img->stride[0]为图像的宽度(此处与img->d_w相等)在ARGB格式的图像中,每个色彩分量占一个字节,取值范围为0~255,所以一个像素占4个字节。switch_rgb_color_t是一个颜色结构体,占4个字节。

代码语言:javascript
代码运行次数:0
复制
10		for(j = 0; j < img->d_h; j++) {
11			for(i = 0; i < img->d_w; i++) {
12				switch_rgb_color_t c = *(switch_rgb_color_t *)(img->planes[0] + j * img->stride[0] + i * 4);
13

取得当前像素的颜色后,第14行将红色分量变为最大值255,即最红,其它分量不变。第15行将颜色写回图像内存。

代码语言:javascript
代码运行次数:0
复制
14				c.r = 255;
15				*(switch_rgb_color_t *)(img->planes[0] + j * img->stride[0] + i * 4) = c;
16			}
17		}

处理结束后,第19行将图像保存到新的文件(命令行上的第二个参数),并于第20行释放内存。

代码语言:javascript
代码运行次数:0
复制
19		switch_img_write_png(img, argv[2]);
20		switch_img_free(&img);
21	}

程序很简单(简单起见没加太多的错误处理语句),用以下命令编译,生成可执行文件c

代码语言:javascript
代码运行次数:0
复制
gcc -o c -I/usr/local/freeswitch/include/freeswitch -L/usr/local/freeswitch/lib -lfreeswitch c.c

不错,至此墨色浓淡,层次感都保存较好啦。还不错吧?

不过,这里还有一点点小问题。那就是《文集》的封面是黄色的,那么墨色越淡就应该越接近于黄色,而不是白色。当然这也难不住我们,我们知道,黄 = 红+绿,所以,只需要将蓝色分量去掉就可以了。在第14行后面加入『c.b = 0;』就将白色变成了黄色。当然,完全去掉蓝色分量会使那个像素变暗,所以,我们把其中一部分加回到绿色分量上,代码片断如下:

代码语言:javascript
代码运行次数:0
复制
14	int g = c.g + c.b / 2;
15	c.r = 255;
16	c.g = g > 255 ? 255 : g;
17	c.b = 0;

加上黄色的底色看看,最终效果看起来还不错吧?

代码语言:javascript
代码运行次数:0
复制
convert wenji-7.png -fuzz 25% -fill none -background yellow -flatten wenji-8.png

没有一个工具是完美的,但工程师总能找到合适的工具解决相应的问题。在看到此文之前,你是不是以为Preview只能用于看图,FreeSWITCH只能用于打电话呢?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeSWITCH中文社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档