如何使用 PDFlib 精确放置裁剪和调整大小的图像?
How to precisely place a cropped and resized image with PDFlib?
为此纠结了几个小时,就是想不通 PDFlib 是如何工作的。我有这张图片,尺寸为 1000 x 300 像素:
现在我想将图像的一部分放入一个 20 x 12 毫米的框中(300 dpi)。调整大小必须使得如果不进行裁剪,图像将在页面上占据 70 x 21 毫米。图片必须从顶部裁剪 3 毫米,从左侧裁剪 2 毫米。
示例和文档太薄弱,我无法准确理解 fit_image()
的参数是如何工作的。我该如何实现?
注意:我在 PHP 中这样做,但我想主要关心的是 PDFlib 需要哪些参数,它与语言无关。
解决这个问题需要几个步骤,当然这很容易实现。您的问题包含各种必须解决的任务:
- 将输入图像缩小到给定区域
- 剪下这张缩小后的图片
- 将缩放和裁剪后的图像放置到给定位置。 (这在您的问题中并不清楚,因此您可以根据需要调整 fit_image() 的 x/y 参数。
这是一种解决方法:
# Load the image
$image = $p->load_image("auto", $imagefile, "");
# First we retrieve the dimension and the resolution for the loaded image
$imagewidth = $p->info_image($image, "imagewidth", "");
$imageheight = $p->info_image($image, "imageheight", "");
$dpix = $p->info_image($image, "resx", "");
$dpiy = $p->info_image($image, "resy", "");
# Calculate the scale factor, to fit the image to a width/height of 70 x 21 mm.
# Use a helper function to calculate the mm-values to the PDF points
$scalex = mm2pt(70) / $imagewidth;
$scaley = mm2pt(21) / $imageheight;
# For demonstrating the correct placing, fit the loaded image with a
# size of 70x21 mm with a light opacity (scaling it to this dimension
# might distort the image ratio) (final code would not include this)
$gstate = $p->create_gstate("opacityfill=.4");
$optlist = sprintf("gstate=%d scale {%f %f} dpi=72",
$gstate, $scalex, $scaley);
$p->fit_image($image, mm2pt(10), mm2pt(250), $optlist);
# Use dpi=72 to ignore the internal DPI value and interpret each image
# pixel without scaling.
# Now, specify the partial area with a matchbox clipping (remember that
# those values are the positions within the 70x21, and y goes from bottom to top)
$optlist = sprintf("scale {%f %f} matchbox={clipping={%f %f %f %f}} dpi=72",
$scalex, $scaley, mm2pt(2)/$scalex, mm2pt(6)/$scaley,
mm2pt(22)/$scalex, mm2pt(18)/$scaley);
# Set the reference point, so the origin of the clipped image will be the
# same as for the original image
$p->fit_image($image, mm2pt(10)+mm2pt(2), mm2pt(250)+mm2pt(6), $optlist);
function mm2pt($mm){
return $mm*2.83465;
}
因此,当使用此代码和 PDFlib 示例图像之一将部分图像放置在原始图像之上时,我得到以下输出:
为此纠结了几个小时,就是想不通 PDFlib 是如何工作的。我有这张图片,尺寸为 1000 x 300 像素:
现在我想将图像的一部分放入一个 20 x 12 毫米的框中(300 dpi)。调整大小必须使得如果不进行裁剪,图像将在页面上占据 70 x 21 毫米。图片必须从顶部裁剪 3 毫米,从左侧裁剪 2 毫米。
示例和文档太薄弱,我无法准确理解 fit_image()
的参数是如何工作的。我该如何实现?
注意:我在 PHP 中这样做,但我想主要关心的是 PDFlib 需要哪些参数,它与语言无关。
解决这个问题需要几个步骤,当然这很容易实现。您的问题包含各种必须解决的任务:
- 将输入图像缩小到给定区域
- 剪下这张缩小后的图片
- 将缩放和裁剪后的图像放置到给定位置。 (这在您的问题中并不清楚,因此您可以根据需要调整 fit_image() 的 x/y 参数。
这是一种解决方法:
# Load the image
$image = $p->load_image("auto", $imagefile, "");
# First we retrieve the dimension and the resolution for the loaded image
$imagewidth = $p->info_image($image, "imagewidth", "");
$imageheight = $p->info_image($image, "imageheight", "");
$dpix = $p->info_image($image, "resx", "");
$dpiy = $p->info_image($image, "resy", "");
# Calculate the scale factor, to fit the image to a width/height of 70 x 21 mm.
# Use a helper function to calculate the mm-values to the PDF points
$scalex = mm2pt(70) / $imagewidth;
$scaley = mm2pt(21) / $imageheight;
# For demonstrating the correct placing, fit the loaded image with a
# size of 70x21 mm with a light opacity (scaling it to this dimension
# might distort the image ratio) (final code would not include this)
$gstate = $p->create_gstate("opacityfill=.4");
$optlist = sprintf("gstate=%d scale {%f %f} dpi=72",
$gstate, $scalex, $scaley);
$p->fit_image($image, mm2pt(10), mm2pt(250), $optlist);
# Use dpi=72 to ignore the internal DPI value and interpret each image
# pixel without scaling.
# Now, specify the partial area with a matchbox clipping (remember that
# those values are the positions within the 70x21, and y goes from bottom to top)
$optlist = sprintf("scale {%f %f} matchbox={clipping={%f %f %f %f}} dpi=72",
$scalex, $scaley, mm2pt(2)/$scalex, mm2pt(6)/$scaley,
mm2pt(22)/$scalex, mm2pt(18)/$scaley);
# Set the reference point, so the origin of the clipped image will be the
# same as for the original image
$p->fit_image($image, mm2pt(10)+mm2pt(2), mm2pt(250)+mm2pt(6), $optlist);
function mm2pt($mm){
return $mm*2.83465;
}
因此,当使用此代码和 PDFlib 示例图像之一将部分图像放置在原始图像之上时,我得到以下输出: