使用裁剪器以减小的尺寸缩放和移动图形 - 是我的方法声音

Zooming and moving a graphic at a reduced size using a cropper - is my method sound?

本文关键字:图形 移动 声音 方法 我的 缩放 裁剪      更新时间:2023-09-26

我希望这个问题在堆栈溢出中没问题。

正在编写一些代码,在这个阶段只解决了 alogrithim,想知道我是否以最好的方式解决这个问题?

这是我需要做的:

拍摄 2000x2000 像素的图像并使用现有的 JS/Jquery 裁剪/缩放库(尚未确定任何特定库 - 欢迎建议),并允许用户移动此图像并放大和缩小,使其适合 1000x1000 区域。 这个"裁剪/缩放"的 1000x1000 区域将是用户的最终输出图像。

但是,在实际的UI中,出于将其适合特定空间的原因,我需要用户以一半的大小工作。 因此,他们的 1000x1000 "最终图像"区域由 500x500 像素区域表示。 希望这是有道理的。

这是我提出的算法:

原始 2000px x 2000px 图像是来源.png

  1. 获取源代码.png并使用 ImageMagick 或类似方法在 PHP 中将其大小调整 50%,并通过 Ajax 将这个新的"临时"1000x1000 图像反馈给我的代码。
  2. 使用裁剪器/缩放器在 500x500 工作区后面显示此临时图像,并允许用户裁剪/移动。
  3. 用户完成后,将裁剪/缩放坐标从缩放器代码发送到裁剪原始源的 PHP 例程.png通过 ImageMagick 将 X,Y,H,W 乘以 2 并将缩放(缩放)除以 2。

我认为这会起作用,并想知道是否有人认为这是最好的方法,或者我错过了一些完全明显的东西。

由于上述含糊不清而编辑:

基本上这是我正在创建的:应用程序输出一个 1000x1000 像素的图像,上面有用户选择的文本(没有提到这一点,以免过于复杂)。2000x2000图像的用武之地是用户可以从多个图像中进行选择,这将是文本后面的背景图像。用户可以移动和缩放该背景图像,以便他们想要的位在最终的 1000x1000 输出中显示为背景。但工作区域只有500x500。

你的方法是完全有效的。事实上,我会选择你的方法而不是替代方案。我会解释...

从本质上讲,您有两种主要方法可以实现您所解释的解决方案。

提出的方法被认为是"后端调整大小"实现,从某种意义上说,您让 ImageMagick 通过 AJAX 获取一些前端输入(图像位置、比例等)。真的只是一些数字。- 但然后在"后端"进行调整大小/存储

你可以做一个"前端调整大小",在这个过程中,你让JavaScript操作获取图像,缩小它,将其重新表达为二进制,然后将其推送到网上。您将需要调整大小/裁剪图像的原始二进制文件,因为调整大小的版本实际上并不存在于磁盘上的任何地方(因此您也无法执行典型的"POST"操作),除非用户首先保存图像并重新上传(这并不理想)

但我会主张后端调整大小...为什么?安全。它远不容易进行前端注入。恶意用户可以加载图像进行裁剪/调整大小,然后使用 JS 注入插入他们选择的新图像(恶意意图。想想裸体等),然后将其发布回您的服务器上。或者更糟糕的是,一个非常聪明的用户可能会在图像中对恶意脚本进行编码,然后在上传到服务器后执行它。

另一个考虑因素是一致性;当你让"中心点"处理大小调整时,你变得不那么依赖JS行为一致(甚至根本不依赖,取决于某些浏览器),就像后端实现一样。

通过

仅通过 AJAX 脚本接受来自用户的几个数字(并正确验证这些数字),恶意用户恶意攻击您的网站的范围要小得多。

当然,通过数学工作很烦人,而不仅仅是挖出完美调整大小的前端内容,但这实际上是一种必需品。

使用ImageMagick怎么样?当然,没有"完美"的工具,否则您将使用它。也就是说,您需要衡量该工具是否最适合您的项目。一些注意事项...

  • 规模:老实说,我们并没有真正使用ImageMagick。这是一个简单的调整大小操作,因此我们可以使用"哑"库来处理它。我们现在使用一个巨大的二进制库来使用 1%的功能,我认为这是浪费服务器上的空间。
  • 部署:想象一下,有一天您发现自己需要迁移到其他托管服务提供商。如果该提供商"不支持"ImageMagick,你会发现自己在重写代码的方式将允许您的网站继续运行。
  • 可用性:如果您知道ImageMagick将在生产服务器。这是一个很棒的库,非常易于使用,特别是对于PHP实现。PHP GD 库更有可能部署在默认的PHP服务器上,并且所有让这些开始需要一些基本的数学(参考我以前的答案,除非你需要一个PHP实现)

综上所述,基于您可能的考虑,我会选择只使用一些简单的 GD PHP 功能(结合"后端调整大小"方法)。

另一种选择是利用代码库,该库更专注于对图像执行光线更改。我为此找到的一个优秀的库是TimThumb。它只是服务器上的一个隐藏的PHP文件 - 你给它一些GET参数(源图像url,目标大小,调整大小模式,一些过滤器,对齐方式......无论您喜欢什么),加载的结果将是请求的图像。它支持缓存请求,以便如果您发现自己经常执行相同的大小调整,它可以轻松返回以前调用的转换。

然而,TimThumb似乎缺乏对明确定位图像的支持,这使它回到了"不是一个好的解决方案"的领域 - 所以坚持使用一些手写的GD PHP函数会很好(除了令人沮丧的冗长的编程命名法,即GD函数名称,眨眼

希望这有帮助! 请参阅我之前的回答以获取有关后端调整大小操作等的帮助

首先,消除"应用程序空间"与"用户空间"的歧义。

如您所指出的,图像(任何给定大小)必须适合 1000x1000 的区域。这将是您的应用程序空间,即应用程序关注的空间。

之后,浏览器不分青红皂白地将应用程序空间调整了 50%......但实际上,这将是您在向用户显示显示器之前应用于显示器的最终转换。这是"用户空间",即用户关注的空间。

综上所述,您只需要确保 2000x2000 图像缩小到给定的应用程序空间(1000x1000)。应用所有这些翻译后,应用最终的 50% 缩小。

但无论如何,你真正想要的是知道拍摄任何大小的图像,并知道缩小多少,以便它按比例适合 1000x1000 的应用程序空间,所以你需要一些数学。

我假设在应用程序中的这一点上您将使用javascript,但它也可以很容易地应用于php。

您需要知道源大小 (2000x2000) 和目标大小 (1000x1000)。只需要一点数学。我认为这就是你想要的,因为我已经意识到这是一种非常常见的编程模式,用于按比例将一件事"拟合"到另一件事中。我觉得每个程序员最终都会学会这个公式......

var source = {w: 2000, h: 2000};
var dest = {w: 1000, h: 1000};
// here's the magic... how many times each source "fits" in the dest along each dimension
var sourceFits = {
   w: dest.w / source.w
   h: dest.h / source.h
};
// In this case, the source can fit x2 along each of the destination dimensions.
// that means that sourceFits.w = 0.5 and sourceFits.h = 0.5. It's a perfect fit
// for either dimension. It doesn't make for a compelling example, but it will work for
// ANY provided source or dest size. 
// So, now that we know how snugly each of the source dimensions fit in the destination,
// we can choose that as the most appropriate scale... lets pick the smaller of the two.
var smallerFits = sourceFits.w > sourceFits.h ? sourceFits.h : sourceFits.w;
// To make the image 'fit inside' we just scale it down by the smaller dimension...
var newSourceSize = {w: source.w * smallerFits, h: source.h * smallerFits}

您的问题有点模糊,因此很难判断这是否确实是您正在寻找的解决方案。希望它适用于您的情况?