【问题标题】:Zooming and moving a graphic at a reduced size using a cropper - is my method sound?使用裁剪器以缩小的尺寸缩放和移动图形 - 我的方法是否合理?
【发布时间】:2016-11-07 09:11:12
【问题描述】:

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

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

这是我需要做的:

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

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

这是我提出的算法:

原始 2000px x 2000px 图片是 source.png

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

我认为这会起作用,并想知道是否有人认为这是这样做的最佳方式,或者我是否遗漏了一些非常明显的东西。

由于上述内容含糊而编辑:

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

【问题讨论】:

    标签: javascript php jquery crop image-scaling


    【解决方案1】:

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

    正如您所指出的,图像(任何给定尺寸)必须适合 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}
    

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

    【讨论】:

    • 感谢您的回复 1owk3y - 非常感谢。这不是我的意思,你是对的,我的问题有点含糊:) 基本上这就是我正在创建的内容:应用程序输出一个 1000x1000 像素的图像,上面有用户选择的文本(没有提到这一点,因为不要过于复杂)。 2000x2000 图像的来源是用户可以从多个图像中进行选择,这将是文本后面的背景图像。用户可以移动和缩放该背景图像,以便他们想要的位在最终的 1000x1000 输出中显示为背景。但是工作区域只有500x500。
    • 嗨,克里斯。我重新阅读了您的问题;我的回答现在似乎不那么相关了。让我再发一个。
    【解决方案2】:

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

    基本上,您有两种主要方法可以实施您所解释的解决方案。

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

    您可以进行 'frontend resize',让 JavaScript 操作获取图像,按比例缩小,将其重新表示为二进制,然后将其推送到网上。您将需要调整大小/裁剪图像的原始二进制文件,因为调整大小的版本实际上并不存在于磁盘上的任何位置(因此您也不能执行典型的“POST”操作),除非用户首先保存图像并重新上传它(这并不理想)

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

    另一个考虑因素是一致性;当您让“中心点”处理大小调整(如后端实现)时,您会减少对 JS 行为一致(甚至完全取决于某些浏览器)的依赖。

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

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

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

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

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

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

    然而,TimThumb appears to lack support for distinctly positioning an image,这让它回到了“不是一个好的解决方案”的领域——所以坚持使用一些手写的 GD PHP 函数会很好地工作(除了令人沮丧的冗长的编程命名法,即 GD 函数名称, 眨眼

    希望这会有所帮助!有关后端调整大小操作等的帮助,请参阅我之前的答案

    【讨论】:

    • 这太棒了,证实了我的想法 :) 非常感谢!
    猜你喜欢
    • 2012-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 2019-10-13
    • 2017-06-18
    相关资源
    最近更新 更多