恢复 javascript 以进行图像裁剪

Posted

技术标签:

【中文标题】恢复 javascript 以进行图像裁剪【英文标题】:Reinstatiating javascript for image crop 【发布时间】:2015-05-11 03:11:55 【问题描述】:

我正在尝试拼凑一个功能,让用户为他们的头像选择图像,使用 javascript 在页面上预览它,使用 jquery 断头台选择裁剪,然后将其上传到带有坐标的服务器可以处理。

到目前为止,我可以选择要上传的图像,它会出现在预览中,但是断头台需要在调用时已经加载图像。有没有一种方法可以在我选择图像时强制断头台重新加载?

这是我的代码:

<head>
<script src="% static "assets/js/user_profile.js" %"></script>
<script type="text/javascript">

    function PreviewImage() 
        var oFReader = new FileReader();
        oFReader.readAsDataURL(document.getElementById("id_avatar").files[0]);

        oFReader.onload = function (oFREvent) 
        document.getElementById("avatar_preview").src = oFREvent.target.result;
        ;
    ;  
</script>
</head>
<body>
    <input type='file' id='id_avatar' name='avatar' onchange="PreviewImage();" /><br />
        <div id="parent" style="width: 300px; height: 300px; overflow: hidden;">
    <img id="avatar_preview" src="#"  style="width:400px;" />
</div>
</body>

这就是我的 user_profile.js 中的内容,这是我在更改头像输入时想要重新实例化的内容:

jQuery(function() 
  var picture = $('#avatar_preview')

  var camelize = function() 
    var regex = /[\W_]+(.)/g
    var replacer = function (match, submatch)  return submatch.toUpperCase() 
    return function (str)  return str.replace(regex, replacer) 
  ()

  var showData = function (data) 
    data.scale = parseFloat(data.scale.toFixed(4))
    for(var k in data)  $('#'+k).html(data[k]) 
  

  picture.on('load', function() 
    picture.guillotine( eventOnChange: 'guillotinechange' )
    picture.guillotine('fit')
    for (var i=0; i<5; i++)  picture.guillotine('zoomIn') 

    // Show controls and data
    $('.loading').remove()
    $('.notice, #controls, #data').removeClass('hidden')
    showData( picture.guillotine('getData') )

    // Bind actions
    $('#controls a').click(function(e) 
      e.preventDefault()
      action = camelize(this.id)
      picture.guillotine(action)
    )

    // Update data on change
    picture.on('guillotinechange', function(e, data, action)  showData(data) )
  )

  // Display random picture
  picture.attr('src', 'img/unsplash.com_' + Math.ceil(Math.random() * 25) + '.jpg')
)

有没有办法将其包装成可以重新加载的内容,而无需重新加载页面并丢失预览?

【问题讨论】:

Jason,我对 Guillotone 不熟悉,所以请原谅我的幼稚,但您能否澄清一下“它会出现在预览中,但 guillotine 需要在请调用它”。在这种情况下,“加载”是什么意思?从浏览器的角度来看,如果图像处于预览状态,肯定会加载图像,那么响应img.onload 事件是否存在问题? 嗨,我的意思是当页面第一次加载时, 标签是空的,因为它是 中内容的预览。 Guillotine 要求 在加载时(加载页面时)已经包含实际图像,因此它不会重新启动。是否可以将 Guillotine 绑定到 img.onload 事件? 代码取自 Guillotine 演示,看起来对您的应用程序基本正确。您可以尝试在picture.guillotine('fit') 之前调用picture.guillotine('remove');,以防picture.onload 事件再次触发。如果您的预览代码正常工作,那么您不需要 picture.attr('src', 'img/unsplash.com_' + Math.ceil(Math.random() * 25) + '.jpg'),这在 Demo 中是必需的。 是否可以将整个 guillotine 调用包含在一个函数中,该函数会在选择输入时被调用? 当然,您可以,但我认为该事件对于加载预览图像来说为时过早。一定要试试,但我认为你已经拥有的更有可能奏效。 【参考方案1】:

通过一些修改,您可以实现您想要的。首先,Guillotine 的 code demo 比 display demo 的代码更容易理解。

每当您设置预览(更改src 属性)时,图像将被加载并且onload 事件将被触发(最终)。您只关心新预览何时完成加载,无需担心文件输入的更改。

因此,每次图像加载完成时,请专注于重新加载插件,例如this。基本上可以归结为:

picture.on('load', function() 
  // Reload the plugin (remove existing instance if any and create a new one)
  if (picture.guillotine('instance')) picture.guillotine('remove')
  picture.guillotine( eventOnChange: 'guillotinechange' )

  // Bind buttons, only once! (to avoid overlaps)
  if (! picture.data('bindedBtns')) 
    picture.data('bindedBtns', true)
    $('#rotate_left').click(function() picture.guillotine('rotateLeft') )
    $('#rotate_right').click(function() picture.guillotine('rotateRight') )
    // ...
  

您可能还会发现Presto 非常有用。它的唯一目的是显示来自文件输入的图像预览。它优雅地回退,寻找显示预览的最佳可用方式。

如果你也将它与Bifrost 配对,最后一次尝试是异步上传图像并从服务器获取预览(不需要 HTML5、XMLHttpRequest 或 Flash),这样你就可以确定你会得到一个在任何浏览器上预览。

很遗憾,我没有时间完成 Presto 的自述文件,但 source 非常干净,在顶部您可以找到有关它的 API 和功能的文档。

希望对你有帮助。

【讨论】:

以上是关于恢复 javascript 以进行图像裁剪的主要内容,如果未能解决你的问题,请参考以下文章

从 Google 照片库加载图像以进行裁剪

java Android - 以编程方式处理图像缩放/裁剪

使用 jcrop 和 java 裁剪图像

使用 CSS 裁剪和拉伸图像以填充页面 [重复]

JPG批量裁剪以生成方形缩略图

如何对齐和裁剪位于子目录中的图像以进行人脸识别?