为啥我的调整剪辑图像大小的脚本不起作用?

Posted

技术标签:

【中文标题】为啥我的调整剪辑图像大小的脚本不起作用?【英文标题】:Why is my script to resize a clipped image not working?为什么我的调整剪辑图像大小的脚本不起作用? 【发布时间】:2014-09-29 00:51:59 【问题描述】:

首先,我为我对 javascript 的一些可悲的知识表示歉意。

我将简要解释我正在尝试做什么 - 我正在尝试设置一组 SIMPLE 函数,以允许用户上传图像、裁剪、旋转和调整结果大小。

我不能 100% 确定这是最好的方法,但这是我目前能想到的唯一方法,所以请多多包涵。我正在使用带有overflow:hidden 的div 和图像上的clip:(rect...) 属性进行剪辑的(可能有些笨拙)方法。

我的resize函数如下:

function ResizeClip(factor) 
    var CropImg = document.getElementById('CroppedPreview');
    var CropContainer = document.getElementById('hiddenCropInner');

    var newHeight = CropImg.offsetHeight * factor;
    var newWidth = CropImg.offsetWidth * factor;
    var newwrapHeight = CropContainer.offsetHeight * factor;
    var newwrapWidth = CropContainer.offsetWidth * factor;

    var cX1 = document.getElementById('qx1').value * factor;
    var cX2 = document.getElementById('qx2').value * factor;
    var cY1 = document.getElementById('qy1').value * factor;
    var cY2 = document.getElementById('qy2').value * factor;

    document.getElementById('qx2').value = cX2;
    document.getElementById('qx1').value = cX1;
    document.getElementById('qy1').value = cY1;
    document.getElementById('qy2').value = cY2;


    CropImg.style.height = newHeight + 'px';
    CropImg.style.width = newWidth + 'px';
    CropImg.style.marginTop = '-' + cY1 + 'px';
    CropImg.style.clip = 'rect(' + cX1 + 'px, ' + cX2 + 'px, ' + cY1 + 'px, ' + cY2 + 'px)';

    CropContainer.style.height = newwrapHeight + 'px';
    CropContainer.style.width = newwrapWidth + 'px';

CroppedPreview 是图片,hiddenCropInner 是在 CSS 中定义了 overflow:hidden 的容器 div。

也许我只是个白痴,但我终其一生都无法弄清楚为什么它不能正常工作。根据我剪辑的图像的哪些部分,图像会四处移动,宽度和高度会以不同的速率放大,从而导致裁剪区域发生变化......

我想做的是调整这个裁剪后的图像的大小(理想情况下,进行其他操作),就好像它是真实的图像一样。有更好的方法吗?否则,我该如何修复该功能?

我将永远感谢任何帮助,但请记住,我是一个完全的新手,真的不知道自己在做什么,所以我需要为我解释清楚一些事情。我没有要求任何人为我做这件事,但我试图想出一些方法来做我想做的事情(轻松调整剪切图像的大小),但没有任何结果。所以,提前感谢您提供的任何帮助!


编辑我现在已经创建了一个小提琴,但令人尴尬的是我什至无法让它工作。尽管如此,它可以在这里找到:http://jsfiddle.net/Xenthide/x62L3/9/

我已经使用从我没有包含的裁剪函数中提取的值任意定义了初始剪辑,因为这在大多数情况下似乎工作正常(嗯,这只会使小提琴过于复杂)。在本地,该代码似乎确实会导致图像大小发生变化,但由于我未知且不可变的原因,小提琴不会......但希望它能让事情变得更清晰......

【问题讨论】:

我是否可以建议定义类似var cropPre = document.getElementById('CroppedPreview'); 和其他类似定义的内容,以避免每次都调用document.getElementById 并获得这样可读性差的代码墙?它也会更快。 谢谢,我已按照建议进行了编辑,并试图使其更具可读性。 我猜CropImg绝对定位?这是强制性的,否则clip 将不起作用。无论如何,你应该修改你的代码,因为你得到的不是很清楚。 我实际上还没有在任何地方定义CroppedPreview 的定位...虽然剪辑最初可以工作,但我能够定义一个裁剪区域,然后从中生成一个裁剪图像。只是调整剪裁图像的大小会导致问题......令人尴尬的是,我也无法让我的小提琴工作......jsfiddle.net/Xenthide/x62L3/9 【参考方案1】:

如果this fiddle很好地代表了你的工作,确实存在一些问题。

首先,您已将inputbutton 元素放入form 元素中:

<form>
    <input type="text" name="qx1" id="qx1" value="74">
    <input type="text" name="qy1" id="qy1" value="63">
    <input type="text" name="qx2" id="qx2" value="367">
    <input type="text" name="qy2" id="qy2" value="220">

    <button id="enlarge" onclick="ResizeClip(1.10)">Enlarge Clip</button>
    <button id="shrink" onclick="ResizeClip(0.9)">Shrink Clip</button>
</form>

现在,如果您没有在这些按钮上指定type 属性,它们默认为type="submit" 按钮。这意味着当您单击它们时,提交表单,简而言之,重新加载页面(这解释了单击按钮时白色闪烁的原因)。无论您的功能是否有效,结果都会因页面重新加载而受到影响。

可以通过以下方法避免这种情况:

    不要将元素包装在 form 中 - 在这种情况下您不需要它。 在表单上的submit 事件上调用.preventDefault(或其他旧版IE 方法)函数。 在按钮上定义type="button"(没有submit 按钮,这应该会阻止在表单字段上按Enter 时提交表单)。

我会使用最后一个。

我们快到了。现在,您的小提琴将不起作用,因为按钮的 click 事件侦听器无法解析 ResizeClip 函数。这是因为ResizeClip 不是全局定义的函数,即使它看起来如此(JSFiddle 在这里没有帮助 - 但它取决于左侧菜单中的“onLoad”选项)。所以你要么:

    全局公开函数,在定义函数后执行window.ResizeClip = ResizeClip 之类的操作。 (提示:定义全局变量和函数被认为是不好的做法。) 从 DOM 中删除传统的事件注册(即按钮上的 onclick 属性)并使用更现代的方法在脚本中附加事件侦听器,从而将表示(html 部分)和逻辑( Javascript)。

我当然会使用最后一个:

<button type="button" id="enlarge">Enlarge Clip</button>
<button type="button" id="shrink">Shrink Clip</button>

在脚本的最后:

document.getElementById("enlarge").onclick = function() ResizeClip(1.1);;
document.getElementById("shrink").onclick = function() ResizeClip(.9);;

在那里,它起作用了! Updated live demo.

嗯,不完全是。它并没有真正剪辑图像,因为正如我告诉你的,你必须为它设置position: absolute。我猜rect 参数需要一些工作。它只是放大和缩小它。但现在你走在了正确的道路上。

【讨论】:

非常感谢!小提琴现在基本上就像我的本地代码一样工作。但是,我不确定我是否仍然完全理解你......当我在 CroppedPreview 上设置“位置:绝对”时,整个事情都会消失,无论是在本地还是在小提琴上......而且,图像被剪裁了,除非我误解了什么这意味着?如果您查看 URL,则原始图像较大,并且显示的图像区域会随着图像的放大和缩小而变化。我认为如果我将所有裁剪坐标更改为与图像尺寸相同的因子,则会显示相同的区域,但显然情况并非如此。 @Xenthide 你看,clip 属性到目前为止还没有任何效果。如果图像看起来被裁剪,那是因为它的容器更小,隐藏了一部分。此外,当您在图像上设置position: absolute 时,它会消失,因为您为clip 计算的值不是很正确(太大),并且会剪切整个图片。如果您仍有问题,我建议 reading the spec carefully 并针对 clip 的值提出一个新的具体问题。 啊,谢谢,我一直把剪辑矩形的顺序弄错了!我实际上根本不需要使用overflow:hidden,这只是令人困惑的事情。 @Xenthide 不客气。但是,如果 *** 上的答案对您有所帮助,请不要忘记接受并最终投票。

以上是关于为啥我的调整剪辑图像大小的脚本不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

如果 Layout 连接到父级,为啥动态调整大小不起作用?

Codeigniter GD 库图像调整大小不起作用

为啥这个调整大小处理程序不起作用? [复制]

为啥手动调整 Visjs 时间线图的高度(可调整大小)不起作用?

使用imagemagick linux脚本裁剪图像不起作用

为啥“自动调整字体”不起作用?