关于imagic拼接透明背景图片的问题
目标:
为了做图片水印,需要水平拼接多个logo和文字。。。
之前用过imagick,所以继续使用。
第一个版本:实现了图片和文字的拼接,代码如下:
package main import (
"fmt" "gopkg.in/gographics/imagick.v2/imagick"
) func draw_setfont(mw *imagick.MagickWand,
dw *imagick.DrawingWand,
font string, size float64,
colour string, sx *float64) {
sflag := false if len(font) > {
dw.SetFont(font)
sflag = true
} if len(colour) > {
pw := imagick.NewPixelWand()
pw.SetColor(colour)
dw.SetFillColor(pw)
pw.Destroy()
sflag = true
} if size > {
dw.SetFontSize(size)
} if sflag {
fm := mw.QueryFontMetrics(dw, " ")
*sx = fm.TextWidth
}
} // sx is the width of a space in the current font and fontsize.
// If the font or fontsize is changed a new value for the space
// width must be obtained before calling this again (by calling draw_setfont)
func draw_metrics(mw *imagick.MagickWand, dw *imagick.DrawingWand, dx *float64, dy, sx float64, text string) {
mw.AnnotateImage(dw, *dx, dy, , text)
mw.DrawImage(dw) // get the font metrics
fm := mw.QueryFontMetrics(dw, text)
if fm != nil {
// Adjust the new x coordinate
*dx += fm.TextWidth + sx
}
} func main() {
imagick.Initialize()
defer imagick.Terminate() mw := imagick.NewMagickWand()
ll := imagick.NewMagickWand()
nn := imagick.NewMagickWand()
bb := imagick.NewMagickWand() fmt.Println("read logo...")
ll.ReadImage("../logo3.png")
nn.ReadImage("../logo2.png")
//加上文字
bb.SetSize(, )
bb.ReadImage("xc:none")
dw := imagick.NewDrawingWand()
var dx, dy, sx float64
dx = //set y
dw.SetFontSize()
dw.SetFont("Times-New-Roman")
fm := bb.QueryFontMetrics(dw, "M")
dy = fm.CharacterHeight + fm.Descender + dw.SetTextEncoding("UTF-8")
dw.SetFont("../yahei.ttf")
fmt.Println("start draw.......")
draw_setfont(bb, dw, "", , "#40FF80", &sx)
fmt.Println("curr:", sx, "dy:", dy)
draw_metrics(bb, dw, &dx, dy, sx, "like......你好。。。")
bb.DrawImage(dw)
bb.WriteImage("font.png") mw.AddImage(ll)
mw.AddImage(nn)
mw.AddImage(bb)
total := mw.MontageImage(ndw, "3x1", "", 0, "0")
total.WriteImage("append.png")
}
实现效果:图片和文字,都已经拼接到一行,拼接方式由 MontageImage 第二个参数决定(Nx1,表示都在一行。。。)
但是有个问题,原先透明的logo图片,拼接到一起,居然没有透明效果了。。。。。
各种查资料,然后第二版来了
package main import (
"fmt" "gopkg.in/gographics/imagick.v2/imagick"
) func draw_setfont(mw *imagick.MagickWand,
dw *imagick.DrawingWand,
font string, size float64,
colour string, sx *float64) {
sflag := false if len(font) > {
dw.SetFont(font)
sflag = true
} if len(colour) > {
pw := imagick.NewPixelWand()
pw.SetColor(colour)
dw.SetFillColor(pw)
pw.Destroy()
sflag = true
} if size > {
dw.SetFontSize(size)
} if sflag {
fm := mw.QueryFontMetrics(dw, " ")
*sx = fm.TextWidth
}
} // sx is the width of a space in the current font and fontsize.
// If the font or fontsize is changed a new value for the space
// width must be obtained before calling this again (by calling draw_setfont) func draw_metrics(mw *imagick.MagickWand, dw *imagick.DrawingWand, dx *float64, dy, sx float64, text string) {
mw.AnnotateImage(dw, *dx, dy, , text)
mw.DrawImage(dw) // get the font metrics
fm := mw.QueryFontMetrics(dw, text)
if fm != nil {
// Adjust the new x coordinate
*dx += fm.TextWidth + sx
}
} func main() {
imagick.Initialize()
defer imagick.Terminate() mw := imagick.NewMagickWand()
ll := imagick.NewMagickWand()
nn := imagick.NewMagickWand()
bb := imagick.NewMagickWand() fmt.Println("read logo...")
ll.ReadImage("../logo3.png")
nn.ReadImage("../logo2.png") //加上文字
bb.SetSize(, )
bb.ReadImage("xc:none")
dw := imagick.NewDrawingWand()
var dx, dy, sx float64
dx = //set y
dw.SetFontSize()
dw.SetFont("Times-New-Roman")
fm := bb.QueryFontMetrics(dw, "M")
dy = fm.CharacterHeight + fm.Descender + dw.SetTextEncoding("UTF-8")
dw.SetFont("../yahei.ttf")
fmt.Println("start draw.......")
draw_setfont(bb, dw, "", , "#40FF80", &sx)
fmt.Println("curr:", sx, "dy:", dy)
draw_metrics(bb, dw, &dx, dy, sx, "like......你好。。。")
bb.DrawImage(dw) mw.AddImage(ll)
mw.AddImage(nn)
mw.AddImage(bb) mw.ResetIterator()
append_img := mw.AppendImages(false)
append_img.WriteImage("append.png")
}
标红的两行代码是关键,如果不调用 ResetIterator,则拼接的终效果是最后一张图片,这里是让迭代器指向第一张图片,重新开始。
AppendImages的参数,true或者false表示上下排列(true),还是水平排列(false)。
OK,到这里,就可以完成目标了。
不得不说,imagick很强大,但是API研究起来还是很头疼呀。
另外,如果你想把一张有背景的图片的 背景去掉,变成透明,那么可以用下面的方法。
// Port of http://members.shaw.ca/el.supremo/MagickWand/trans_paint.htm to Go
package main import "gopkg.in/gographics/imagick.v2/imagick" func main() {
imagick.Initialize()
defer imagick.Terminate() mw := imagick.NewMagickWand()
mw.ReadImage("logo:") // A larger fuzz value allows more colours "near" white to be
// modified. A fuzz of zero only allows an exact match with the
// given colour
// Set up the pixelwand containing the colour to be "targeted"
// by transparency
target := imagick.NewPixelWand()
target.SetColor("white")
// Change the transparency of all colours which match target (with
// fuzz applied). In this case they are made completely transparent (0)
// but you can set this to any value from 0 to 1.
mw.TransparentPaintImage(target, 0, 10, false)
mw.WriteImage("logo_white.png")
}
但是这个方法也不是万能的,SetColor用来指定需要去处的背景色,程序会查找相似的颜色,并去掉,然后编程透明。
关于imagic拼接透明背景图片的问题的更多相关文章
- 网页中PNG透明背景图片的完美应用
PNG 图片在网站设计中是不可或缺的部分,最大的特点应该在于 PNG 可以无损压缩,而且还可以设置透明,对于增强网站的图片色彩效果有重要的作用. 但为什么 PNG 图片却没有 GIF 和 JPG 图片 ...
- Qt 制作透明背景图片与裁剪图片(很实用)
这两天想做一个五子棋游戏,想从零开始自己绘制各种图片素材,将经验心得整理如下. 制作透明背景图片: void MyPainter::DrawKit() { QImage image(30, 30, Q ...
- vc下打印透明背景图片
一.前言 刚接到个任务,要把带有透明背景的章子图片打印出来,开始觉得不是很简单吗,直接用vc自动生成的打印功能不就ok了.不过问题却不是想像的那么简单! 二.窗口中显示透明图片 在窗口中显示图片,可以 ...
- 【计算机视觉】OPENCV对于有alpha通道的透明背景图片的读取和图片叠加
这个是我自己做的粗略的螺旋丸的图,导出为png并带有alpha通道. 最后和一只狗合成成这个样子. 效果还是可以的. 为了实现这个效果,首先我们要明白具有透明通道的图片的OpenCV的读取方式.在Op ...
- C++ 设置透明背景图片
背景: 有两个图片,一个是目标背景图片, 一个是带有自身背景色彩的彩色图片 先将这彩色图片绘制到目标背景图片中, 这一步通过BITBLT就可实现. 但实 ...
- java 生成透明背景图片
//开始绘图 graphics2d.setBackground(Color.WHITE); graphics2d.clearRect(0, 0, width, height); graphics2d. ...
- php 处理透明背景的图片时的问题
PHP图象处理之透明背景的gif和png图片的一些问题 1,直接读取有透明背景的PNG格式文件,然后直接输出,背景变成了黑色,gif则没有这种情况. 解决方法:使用 imagesavealpha ...
- css透明背景兼容方案
css透明是一个技术活,因为这里面涉及到了IE8及以下版本不兼容opacity这个css3属性,而filter:alpha(opacity=80)这个值则是不兼容IE6.网上比较流行的透明css是这样 ...
- DD_belatedPNG.js解决透明PNG图片背景灰色问题
<!--[]> <script type="text/javascript" src="http://www.phpddt.com/usr/themes ...
随机推荐
- jQuery-表单流程导航
前言:以前做过一个项目,里面牵涉到流程相关的业务,需要用到流程页面导航的效果,完整的工作流相关的项目以前也做过,需要用到第三方插件,当然这里记录的业务需求没这个麻烦,仅仅需要能有一个页面导航的标题栏, ...
- Spark Streaming源码解读之Driver容错安全性
本期内容 : ReceivedBlockTracker容错安全性 DStreamGraph和JobGenerator容错安全性 Driver的安全性主要从Spark Streaming自己运行机制的角 ...
- 【ORM】--FluentNHibernate之基本映射详解
最近在做项目的时候用到了NHibernate,使用它并不困难,但是很麻烦.如果我的数据库有几百张表如果想要一个个的映射岂不是很麻烦,所以这种情况下使用NHibernate就会很笨重,虽然 ...
- 自己用C语言写单片机PIC18 serial bootloader
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). HyperBootlo ...
- springmvc+mybatis整合
maven 依赖 <!-- springmvc --> <dependency> <groupId>org.springframework</groupId& ...
- IT在线笔试总结(二)
1. 循环队列的长度计算:对于非循环队列,尾指针与头指针的差值便是队列长度,而对于循环队列,差值可能为负数,因此需要将差值加上MAXQSIZE再与MAXQSIZE求余. 2. 算法的时间复杂度取决于: ...
- Android应用开发项目结构分析
初学Android开发,初步理解的Android应用项目结构,备忘. 一.清单文件AndroidManifest.xml 功能: 1.供Android平台调用,供其了解本应用的信息,因此,所有的组件( ...
- SQL Server 的数据表简单操作
--创建数据表--[use 要创建数据表的数据库名称go]create table 要创建的表名(字段名 数据类型[长度] [null | not null] [primary key],... .. ...
- [Tomcat 源码分析系列] (一) : Tomcat 启动脚本-startup.bat
概述 我们通常使用 Tomcat 中的 startup.bat 来启动 Tomcat. 但是这其中干了一些什么事呢? 大家都知道一个 Java 程序需要启动的话, 肯定需要 main 方法, 那么这个 ...
- sublime 关闭自动更新
第一步: 点击菜单栏“Preferences”=> "Settings-User" 进入个人参数设置页面: 第二步: 在大括号内插入如下代码:"update_che ...