从缩小的图像转换选择坐标
Posted
技术标签:
【中文标题】从缩小的图像转换选择坐标【英文标题】:Translating selection coordinates from a downscaled image 【发布时间】:2013-09-04 20:14:25 【问题描述】:我正在为网站构建一个简单的图像裁剪实用程序。
我遇到了一个小问题:每次我这样做时都会出现失真(我的选择坐标是粗略估计的,因此例如以错误的尺寸绘制图像)。
我画了这个是为了让你明白我的意思:
这里有一些代码可以帮助您获得我想要实现的目标:
//Get the new coordinates to crop the image.
$x1 = $request->getPost('x1');
$y1 = $request->getPost('y1');
$x2 = $request->getPost('x2');
$y2 = $request->getPost('y2');
$w = $request->getPost('w');
$h = $request->getPost('h');
$croptool_width = $request->getPost('croptool_width');
$croptool_height = $request->getPost('croptool_height');
$original_width = $request->getPost('original_width');
$original_height = $request->getPost('original_height');
$infos = pathinfo($original_image_location);
$extension = strtolower($infos['extension']);
switch($extension)
case 'gif':
$sourceImage = imagecreatefromgif($original_image_location);
break;
case 'jpg':
case 'jpeg':
$sourceImage = imagecreatefromjpeg($original_image_location);
break;
case 'png':
$sourceImage = imagecreatefrompng($original_image_location);
break;
// Take croptool's dimension, transpose selection coordinates to fit the original image.
$scale_y = $original_height / $croptool_height;
$scale_x = $original_width / $croptool_width;
$scaled_x1 = $x1 * $scale_x;
$scaled_y1 = $y1 * $scale_y;
$scaled_x2 = $x2 * $scale_x;
$scaled_y2 = $y2 * $scale_y;
// Crop selection and save to disk
$cropImage = imagecreatetruecolor(Model_Wineries::getCoverImageWidth(), Model_Wineries::getCoverImageHeight());
imagecopyresampled(
$cropImage, $sourceImage,
0, 0,
$scaled_x1, $scaled_y1,
Model_Wineries::getLogoImageWidth(), Model_Wineries::getLogoImageHeight(),
$scaled_x2, $scaled_y2
);
if (file_exists($cover_image_location))
unlink($cover_image_location);
imagejpeg($cropImage, $cover_image_location, 90);
chmod($cover_image_location, 0777);
if (file_exists($original_image_location))
unlink($original_image_location);
我无法弄清楚的部分是如何正确计算$scale
变量。
$croptool_width 和 $croptool_height 都是缩小后的尺寸。 $original_... 是原始的。
有人可以帮帮我吗?
编辑:建议的回复很好,但由于某种原因,所做的任何事情都完全错误,请看这里:
编辑:(代码已更新)
谢谢!
【问题讨论】:
退后一步,让我们忽略该代码。你想要达到什么,而不是你已经拥有什么。您的脚本是否收到图像和裁剪坐标/尺寸,然后应该生成该裁剪?如果是这样,请考虑使用php.net/manual/en/book.imagick.php 为您完成这项工作。 您是否尝试更改宽高比?我已经发布了一个anwser。 ImageMagick 通过命令行工作,您可以使用 exec() 或 PHP 或 Java 中的任何内容,它经过了令人难以置信的良好测试、稳定和广泛支持。您还可以独立于您的服务器测试命令行调用和坐标,以获得您需要的东西。我第二个@Mike'Pomax'Kamermans 还有一个 PHP imagemagick API,所以你不需要 exec。大多数函数都可以直接从 PHP 获得 【参考方案1】:可能是我误解了,但我认为您计算的是“比例”而不是“比例”。比例尺是原始尺寸与新尺寸的乘积。可能是:
$scale_y = $original_height / $croptool_height;
$scale_x = $original_width / $croptool_width;
$scaled_x1 = $x1 * $scale_x;
$scaled_y1 = $y1 * $scale_y;
$scaled_x2 = $x2 * $scale_x;
$scaled_y2 = $y2 * $scale_y;
//Original height = 1000 and Croptool height = 100 ==> scale_y = 10; Pixel (0, 45) on crop space == 45 * 10 == 450 on original image.
//Original height = 100 and Croptool height = 1000 ==> scale_y = 0.10; Pixel (0, 450) on crop space == 450 * 0.10 == 45 on original image.
希望这会有所帮助。
编辑:
我不熟悉PHP API,但是看起来提供的源宽度和源高度是错误的,可能你可以计算为
imagecopyresampled(
$cropImage, $sourceImage,
0, 0,
$scaled_x1, $scaled_y1,
Model_Wineries::getLogoImageWidth(), Model_Wineries::getLogoImageHeight(),
$scaled_x2 - $scaled_x1, $scaled_y2 - $scaled_y1
);
【讨论】:
它几乎可以工作,但它们仍然有点失真。例如,如果我选择这个:cl.ly/image/0L1Q1w441500 我得到这个结果:cl.ly/image/0c1x3H0K0Z1k 非常感谢!【参考方案2】:你可以试试这个:
original width * new height / original height = new width;
original height * new width / original width = new height;
[1]Get aspect ratio from width and height of image (PHP or JS)
【讨论】:
【参考方案3】:我不确定这是否是完整的解决方案,但您在这里遇到了问题:
imagecopyresampled(
$cropImage, $sourceImage,
0, 0,
$scaled_x1, $scaled_y1,
Model_Wineries::getLogoImageWidth(), Model_Wineries::getLogoImageHeight(),
$scaled_x2, $scaled_y2
);
根据此函数的 php 文档,最后两个参数应该是源图像的宽度和高度,但您传递的是坐标。所以不是$scaled_x2,而是通过$scaled_x2-$scaled_x1,而不是$scaled_y2,而是通过$scaled_y2-$scaled_y1
【讨论】:
以上是关于从缩小的图像转换选择坐标的主要内容,如果未能解决你的问题,请参考以下文章