【问题标题】:How can I center captions in PerlMagick?如何在 PerlMagick 中将字幕居中?
【发布时间】:2010-10-14 09:18:17
【问题描述】:

我可以说在命令行上使用 ImageMagick

convert -background '#0000' -fill white -stroke black -strokewidth 3 -gravity center -pointsize 78 -size 568x1000 caption:'Lorem ipsum etc etc' -trim +repage out.png

并产生我正在寻找的输出。我想做的是同样的事情,但在 PerlMagick 中,这样我就不必在执行各种其他步骤时继续读取和写入文件。这是我目前所拥有的

use strict;
use warnings;
use Image::Magick;

my $im = new Image::Magick;
my $e = $im->Set(
        background => '#0000',
        fill => 'white',
        stroke => 'black',
        strokewidth => 3,
        gravity => 'center',
        pointsize => 78,
        size => '586x1000',
);
die $e if $e;

$e = $im->Read("caption:Lorem ipsum etc etc");
die $e if $e;

$e = $im->Trim();
die $e if $e;

$e = $im->Set(page=>'0x0+0+0'); # +repage
die $e if $e;

$e = $im->Write('out.png');
die $e if $e;

除了结果文本没有居中之外,它的工作方式完全相同。

PerlMagick 上的文档几乎不存在。我将这种“阅读标题”语法基于一些 MagicWand 示例,据称这将导致文本居中。 PerlMagick 显然有些不同。

所以,问题是:在这种情况下,我怎样才能让 PerlMagick 尊重重力?如何通过 PerlMagick 获得多行、居中和自动换行的文本?请注意,这要求我使用标题而不是注释或绘制。我宁愿避免手动每行居中,但我会考虑。

或者,如果有人有做自动换行、使用比例字体和注释的示例,那么这对我有用。

编辑:请注意,宝丽来的 -caption 选项虽然与我正在做的事情共享实现,但与标题不同:伪图像。如果输出与上面示例转换命令给出的内容非常匹配,我仍然会接受使用宝丽来和 -caption 的答案。

编辑 2:这是一个更简单的问题示例。

use strict;
use warnings;
use Image::Magick;

my $im = new Image::Magick;
my $e = $im->SetAttribute(
        background => '#0000',
        pointsize=>12,
        size => '100x100',
        gravity => 'center',
);
die $e if $e;
$e = $im->ReadImage('caption:The quick brown fox jumps over the lazy dog.');
die $e if $e;
$e = $im->Write('out.png');
die $e if $e;

预期结果:文本居中。

实际结果:文本左对齐。

实际结果应该与此命令的输出相同:

convert -background '#0000' -size 100x100  -pointsize 12 -gravity center caption:'The quick brown fox jumps over the lazy dog.' out.png

通过查看 perlmagick 源,我看不到任何应该拦截特定 SetAttribute 调用的内容,所以我不明白为什么忽略重力。我怎样才能让重力不被忽视?或者,我还能如何使用这种输出进行自动换行和居中文本?

【问题讨论】:

  • 这个没试过,不知道这里有没有可以重复使用的东西。 code.google.com/p/image-boxmodel/source/browse/trunk/lib/Image/…
  • 我会在几个小时后下班回家试试。我最终的解决方法是让 PerlMagick 以不同的点大小重复执行非居中渲染,直到生成的图像在我的盒子大小内。然后我调用通过 system() 进行转换并让它执行最终渲染。然而,它使用的 CPU 能力是真正的原生解决方案的许多倍,所以我仍在尝试,但至少我有一些可以依靠的东西。

标签: perl imagemagick


【解决方案1】:

使用 Annotate() 怎么样?

use strict;
use warnings;
use Image::Magick;

my $im = Image::Magick->new();
$im->Set(size => "1000x568");
$im->ReadImage('xc:black');
$im->Annotate(text => "Lorem ipsum etc etc",
              gravity => "Center",
              fill => 'white',
              stroke => 'black',
              strokewidth => 3,
              pointsize => 78);
$im->Write('myout.png');

【讨论】:

  • 这不是自动换行的。尝试添加更多文本直到需要换行,或者像我的原始示例一样将大小设为 568 像素宽,看看会发生什么。仅供参考,根据 imagemagick 文档,您不能使用 Annotate 或 Draw 自动换行,只能使用标题。
  • 一个涉及 Annotate 或 Draw 的答案必须包含代码来分割输入字符串并在适当的地方换行,同时考虑到比例字体。这是可能的(QueryFontMetrics)但很困难,特别是如果您还需要像我一样“最适合”预定义的框,同时最大限度地减少文本行数并最大化字体大小。
【解决方案2】:

版本:ImageMagick 6.5.7-8

更接近,但仍然没有水平居中,只是垂直居中。有点想不通了...

#!/usr/bin/perl

use strict;
use warnings;
use Image::Magick;

my $t = Image::Magick->new();
my $b = Image::Magick->new();
$t->SetAttribute(pointsize=>12, size => '100x50', background=>'transparent');
$b->SetAttribute(size => '100x100');
$t->ReadImage('caption:The quick brown fox jumps over the lazy dog.');
$b->ReadImage('xc:transparent');
$b->Composite(image => $t, gravity=>'center', compose=>'over');
$b->Write('out.png');

【讨论】:

  • 我原来的例子也让我走到了这一步。这就是问题所在:在 Magick.xs 中,在解析“重力”选项时,会出现这样的循环:for( ; image ; image = image->next ) image->gravity = (MagickGravity)sp;(请注意,确切的变量名称可能有点偏差,因为这是来自内存)。因此,如您所见,它为每个图像设置了重力。但是,此时没有图像(图像为 NULL),当 ReadImage 创建 new 图像时,它显然没有这个重力值。这是我昨天查看 imagemagick 源代码时学到的。
  • 我也许应该提到,当您阅读标题:图像类型时,它会立即呈现带有可用选项的文本,并且似乎不需要等待例如一个复合步骤。这就是“重力”不能像您在此处使用的方式起作用的原因:文本已经被呈现为左对齐。
  • 似乎在命令行上的转换和为此的 C API 都通过了 wand 系统,这是不同的,实际上是你所期望的。奇怪的是,如果您正在运行 convert(1),似乎永远不会命中 caption.c 的 ReadCAPTIONImage,这有点令人费解(我仍在研究那个)。
  • 我赞成并接受这个,即使它不是完全的解决方案。通过我的调查,我发现由于 PerlMagick 的缺陷,实际上没有本地解决方案。在使用纯 PerlMagick 解决方案(而不是先修补 imagemagick)时,您确实与任何人一样接近。
【解决方案3】:

这适用于我的 Ubuntu 10.04。我只看到使用“宝丽来”效果的“标题”文档。

#!/usr/bin/perl

use strict;
use warnings;
use Image::Magick;

my $im = new Image::Magick;
$im->Set(size => '586x1000');

my $e = $im->ReadImage('xc:black');

$im->Polaroid(
        fill => 'white',
        stroke => 'black',
        strokewidth => 3,
        gravity => 'center',
        pointsize => 78,
        caption => "Lorem ipsum etc etc"
);

$e = $im->Trim();
die $e if $e;

$e = $im->Set(page=>'0x0+0+0'); # +repage
die $e if $e;

$e = $im->Write('out.png');
die $e if $e;

【讨论】:

  • PerlMagick 的好示例代码在这里:imagemagick.org/source/examples.pl
  • 请发布您的确切 imagemagick 和 perlmagick 版本。你可以在这里找到这样使用的标题示例:imagemagick.org/Usage/text/#caption(请注意宝丽来使用 -caption,而这是伪图像标题:)另外请注意,我将使用它在顶部应用文本不得应用宝丽来效果的现有图像。
  • 此外,使用此技术生成的图像还不够。此特定步骤应生成具有透明背景的图像,该背景足够大以容纳呈现的文本(与运行上面给出的命令行版本的结果完全相同)。
猜你喜欢
  • 2020-10-26
  • 2014-03-24
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-30
  • 2022-12-05
  • 1970-01-01
相关资源
最近更新 更多