简体   繁体   English

图片上传前调整大小

[英]Image resize before upload

I need to provide a means for a user to upload photos to their web site in jpeg format.我需要提供一种方法让用户以 jpeg 格式将照片上传到他们的网站。 However, the photos are very large in original size, and I would like to make the resize before upload option very effortless for the user.但是,这些照片的原始尺寸非常大,我想让用户轻松地在上传选项之前调整大小。 It seems my only options are a client side application that resizes the photos before uploading them via a web service, or a client side JavaScript hook on the upload operation that resizes the images.似乎我唯一的选择是客户端应用程序在通过 Web 服务上传照片之前调整照片大小,或者在上传操作上调整图像大小的客户端 JavaScript 钩子。 The second option is very tentative because I don't have a JavaScript image resizing library, and it will be difficult to get the JavaScript to run my current resize tool, ImageMagick.第二个选项是非常暂定的,因为我没有 JavaScript 图像大小调整库,而且很难让 JavaScript 运行我当前的调整大小工具 ImageMagick。

I'm sure this is not too uncommon a scenario, and some suggestions or pointers to sites that do this will be appreciated.我相信这种情况并不少见,我们将不胜感激提供一些建议或指向执行此操作的站点的指示。

In 2011, we can know do it with the File API, and canvas.在 2011 年,我们可以知道使用 File API 和 canvas 来实现。 This works for now only in firefox and chrome.这目前仅适用于 Firefox 和 chrome。 Here is an example :这是一个例子:

var file = YOUR_FILE,
    fileType = file.type,
    reader = new FileReader();

reader.onloadend = function() {
  var image = new Image();
      image.src = reader.result;

  image.onload = function() {
    var maxWidth = 960,
        maxHeight = 960,
        imageWidth = image.width,
        imageHeight = image.height;

    if (imageWidth > imageHeight) {
      if (imageWidth > maxWidth) {
        imageHeight *= maxWidth / imageWidth;
        imageWidth = maxWidth;
      }
    }
    else {
      if (imageHeight > maxHeight) {
        imageWidth *= maxHeight / imageHeight;
        imageHeight = maxHeight;
      }
    }

    var canvas = document.createElement('canvas');
    canvas.width = imageWidth;
    canvas.height = imageHeight;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(this, 0, 0, imageWidth, imageHeight);

    // The resized file ready for upload
    var finalFile = canvas.toDataURL(fileType);
  }
}

reader.readAsDataURL(file);

There is multiple-technology-capable Plupload tool which declares that it can do resizing before upload, but I haven't tried it yet.有多种技术能力的Plupload工具,它声明它可以在上传之前调整大小,但我还没有尝试过。 I have also find a suitable answer in my question about binary image handling javascript libs .我还在关于二进制图像处理 javascript libs 的问题中找到了合适的答案。

You have several options:您有多种选择:

  1. Java爪哇
  2. ActiveX (only on windows) ActiveX(仅在 Windows 上)
  3. Silverlight银光
  4. Flash闪光
  5. Flex 柔性
  6. Google Gears (the most recent version is capable of resizing and drag and drop from your desktop) Google Gears (最新版本能够从桌面调整大小和拖放)

I've done a lot of research looking for a similar solution to what you have described and there a lot of solutions out there that vary a lot in quality and flexibility.我进行了大量研究,寻找与您所描述的类似的解决方案,并且有很多解决方案在质量和灵活性上差异很大。

My suggestion is find a solution which will do 80% of what you need and customize it to suit your needs.我的建议是找到一个解决方案,它可以满足您 80% 的需求,并对其进行定制以满足您的需求。

I think you need Java or ActiveX for that.我认为你需要 Java 或 ActiveX。 For example Thin Image Upload例如薄图像上传

What jao and russau say is true. jao 和 russau 说的是真的。 The reason being is JavaScript does not have access to the local filesystem due to security reasons.原因是出于安全原因,JavaScript 无法访问本地文件系统。 If JavaScript could "see" your image files, it could see any file, and that is dangerous.如果 JavaScript 可以“看到”您的图像文件,它就可以看到任何文件,这很危险。

You need an application-level control to be able to do this, and that means Flash, Java or Active-X.您需要应用程序级控件才能执行此操作,这意味着 Flash、Java 或 Active-X。

Here some modifications to feed tensorflow.js(soo fast with it!!) with resized and cropped image (256x256px), plus showing original image under cropped image, to see what is cut off.这里有一些修改以使用调整大小和裁剪图像(256x256px)来馈送 tensorflow.js(用它太快了!!),加上在裁剪图像下显示原始图像,以查看被截断的内容。

$("#image-selector").change(function(){


var file = $("#image-selector").prop('files')[0];   

var maxSize = 256;  // well now its minsize
var reader = new FileReader();
var image = new Image();
var canvas = document.createElement('canvas');
var canvas2 = document.createElement('canvas');     

var dataURItoBlob = function (dataURI) {
    var bytes = dataURI.split(',')[0].indexOf('base64') >= 0 ?
        atob(dataURI.split(',')[1]) :
        unescape(dataURI.split(',')[1]);
    var mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
    var max = bytes.length;
    var ia = new Uint8Array(max);
    for (var i = 0; i < max; i++)
        ia[i] = bytes.charCodeAt(i);
    return new Blob([ia], { type: mime });
};

var resize = function () {
    var width = image.width;
    var height = image.height; 

    if (width > height) {           
        if (width > maxSize) { 
            width *= maxSize / height; 
            height = maxSize;
        }
    } else {
        if (height > maxSize) {
            height *= maxSize / width;
            width = maxSize;
        }           
    }
    if (width==height) { width = 256; height = 256; }


    var posiw = 0;
    var posih = 0;
    if (width > height) {posiw = (width-height)/2; }
    if (height > width) {posih = ((height - width) / 2);} 
    canvas.width = 256;
    canvas.height = 256;
    canvas2.width = width;
    canvas2.height = height;        
     console.log('iw:'+image.width+' ih:'+image.height+' w:'+width+' h:'+height+' posiw:'+posiw+' posih:'+posih);
    canvas.getContext('2d').drawImage(image, (-1)*posiw, (-1)*posih, width, height); 
    canvas2.getContext('2d').drawImage(image, 0, 0, width, height); 
    var dataUrl = canvas.toDataURL('image/jpeg');
    var dataUrl2 = canvas2.toDataURL('image/jpeg');     

        if ($("#selected-image").attr("src")) {
            $("#imgspeicher").append('<div style="width:100%; border-radius: 5px; background-color: #eee; margin-top:10px;"><div style="position: relative; margin:10px auto;"><img id="selected-image6" src="'+$("#selected-image").attr("src")+'" style="margin: '+document.getElementById('selected-image').style.margin+';position: absolute; z-index: 999;" width="" height=""><img id="selected-image2" src="'+$("#selected-image2").attr("src")+'" style="margin: 10px; opacity: 0.4;"></div><div class="row" style="margin:10px auto; text-align: left;"> <ol>'+$("#prediction-list").html()+'</ol> </div></div>');
        }

    $("#selected-image").attr("src",dataUrl);
    $("#selected-image").width(256);
    $("#selected-image").height(256);
    $("#selected-image").css('margin-top',posih+10+'px');
    $("#selected-image").css('margin-left',posiw+10+'px');      
    $("#selected-image2").attr("src",dataUrl2); 
    $("#prediction-list").empty();
    console.log("Image was loaded, resized and cropped");
    return dataURItoBlob(dataUrl);



};

return new Promise(function (ok, no) {

    reader.onload = function (readerEvent) {
        image.onload = function () { return ok(resize()); };
        image.src = readerEvent.target.result;
    };

let file = $("#image-selector").prop('files')[0];       
reader.readAsDataURL(file);});}); 

Html implementation: html实现:

<input id ="image-selector" class="form-control border-0" type="file">

<div style="position: relative; margin:10px auto; width:100%;" id="imgnow">
 <img id="selected-image" src="" style="margin: 10px; position: absolute; z-index: 999;">
 <img id="selected-image2" src="" style="margin: 10px; opacity: 0.4;">                       
</div> 

Also not resize to a maximum width/height, but to minimum.也不会调整到最大宽度/高度,而是调整到最小。 We get a 256x256px square image.我们得到一个 256x256px 的方形图像。

Unfortunately you won't be able to resize the images in Javascript.不幸的是,您将无法在 Javascript 中调整图像大小。 It is possible in Silverlight 2 tho.在 Silverlight 2 中是可能的。

If you want to buy something already done: Aurigma Image Uploader is pretty impressive - $USD250 for the ActiveX and Java versions.如果您想购买已经完成的东西: Aurigma Image Uploader非常令人印象深刻 - ActiveX 和 Java 版本为 250 美元。 There's some demos on the site, I'm pretty sure facebook use the same control.网站上有一些演示,我很确定 facebook 使用相同的控件。

Pure JavaScript solution.纯 JavaScript 解决方案。 My code resizes JPEG by bilinear interpolation, and it doesn't lose exif.我的代码通过双线性插值调整 JPEG 大小,并且不会丢失 exif。

https://github.com/hMatoba/JavaScript-MinifyJpegAsync https://github.com/hMatoba/JavaScript-MinifyJpegAsync

function post(data) {
    var req = new XMLHttpRequest();
    req.open("POST", "/jpeg", false);
    req.setRequestHeader('Content-Type', 'image/jpeg');
    req.send(data.buffer);
}

function handleFileSelect(evt) {
    var files = evt.target.files;

    for (var i = 0, f; f = files[i]; i++){
        var reader = new FileReader();
        reader.onloadend = function(e){
            MinifyJpegAsync.minify(e.target.result, 1280, post);
        };
        reader.readAsDataURL(f);
    }
}

document.getElementById('files').addEventListener('change', handleFileSelect, false);

You can resize the image in the client-side before uploading it using an image processing framework.您可以在使用图像处理框架上传图像之前在客户端调整图像大小。

Below I used MarvinJ to create a runnable code based on the example in the following page: "Processing images in client-side before uploading it to a server"下面我使用MarvinJ根据以下页面中的示例创建了一个可运行的代码: “在将图像上传到服务器之前在客户端处理图像”

Basically I use the method Marvin.scale(...) to resize the image.基本上我使用Marvin.scale(...)方法来调整图像大小。 Then, I upload the image as a blob (using the method image.toBlob() ).然后,我将图像作为 blob 上传(使用方法image.toBlob() )。 The server answers back providing a URL of the received image.服务器回复提供接收图像的 URL。

 /*********************************************** * GLOBAL VARS **********************************************/ var image = new MarvinImage(); /*********************************************** * FILE CHOOSER AND UPLOAD **********************************************/ $('#fileUpload').change(function (event) { form = new FormData(); form.append('name', event.target.files[0].name); reader = new FileReader(); reader.readAsDataURL(event.target.files[0]); reader.onload = function(){ image.load(reader.result, imageLoaded); }; }); function resizeAndSendToServer(){ $("#divServerResponse").html("uploading..."); $.ajax({ method: 'POST', url: 'https://www.marvinj.org/backoffice/imageUpload.php', data: form, enctype: 'multipart/form-data', contentType: false, processData: false, success: function (resp) { $("#divServerResponse").html("SERVER RESPONSE (NEW IMAGE):<br/><img src='"+resp+"' style='max-width:400px'></img>"); }, error: function (data) { console.log("error:"+error); console.log(data); }, }); }; /*********************************************** * IMAGE MANIPULATION **********************************************/ function imageLoaded(){ Marvin.scale(image.clone(), image, 120); form.append("blob", image.toBlob()); }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script> <form id="form" action='/backoffice/imageUpload.php' style='margin:auto;' method='post' enctype='multipart/form-data'> <input type='file' id='fileUpload' class='upload' name='userfile'/> </form><br/> <button type="button" onclick="resizeAndSendToServer()">Resize and Send to Server</button><br/><br/> <div id="divServerResponse"> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM