Project practice form form for picture uploading or base64 front end picture compression of front end picture compression

  • 2021-07-06 10:07:30
  • OfStack

The first project has finally been launched. It is a public welfare crowdfunding platform called Pro-Qingchou. I have completed most of the WeChat, computer and background interfaces. Over the past few months, I feel that I have gained a lot, and I feel that I need to summarize it.

The first thing that comes to mind is the problem of uploading pictures. It's stupid to use an form form in order to upload a picture when the form data is usually uploaded on ajax. Then I didn't think of using jquery form plug-in at that time.

The scheme given by colleagues in the background is to write an form form in iframe, and then submit the form automatically after uploading the picture. He will jump the address of the picture on the server to the first part of the page url, and I will intercept it again.

Scenario 1: iframe+form form


<form action="/user/uploadIdCard.do" class="fileForm picUpload" enctype="multipart/form-data" method="post">
<input type="file" id="uploadPic" name="file">
<label for="uploadPic" id="fileBtn">
+
<img src="" />
</label>
<input type="text" name="turnUrl" class="turnUrl">
</form> 
$(".turnUrl").val(window.location.pathname);
$("#uploadPic").on('change', function(event) {
event.preventDefault();
$("form").submit();
});

Introducing iframe in the interface that needs to upload pictures, calling iframe method in the common library, obtaining url of pictures and displaying pictures in iframe


//  Extraction iframe The path in the 
function iframe(el) {
var baseurl = "";
var code, filePath;
var place = $(el)[0].contentWindow.location.search;
console.log(place);
if (place) {
code = place.match(/code=\d+/)[0].substr(5);
if (place.match(/filepath=\S+/)) {
filePath = place.match(/filepath=\S+/)[0].substr(9);
}
$(el).contents().find(".tip").css('color', '#d0021b');
console.log(filePath);
switch (code) {
case "200":
$(el).contents().find(".tip").text(' Upload succeeded ');
$(el).contents().find(".tip").css('color', '#55a012');
$(el).contents().find("#fileBtn>img").show().attr("src", baseurl + "/" + filePath);
return "/" + filePath;
case "206":
$(el).contents().find(".tip").text(' File is too large ');
break;
case "207":
$(el).contents().find(".tip").text(' Wrong file type ');
break;
case "208":
$(el).contents().find(".tip").text(' System error ');
}
}
}

Scheme 2: Later, it was found that there were two problems in this practice. One was that the picture sent by the user was too large, and the background was not compressed (the colleagues in the background were too busy, so in order to accommodate them, we compressed the front end).

The second is that after uploading the picture successfully, the picture is displayed on iframe, which requires a fixed reaction time. Users sometimes report that the picture cannot be transmitted, but in fact, the background has not returned yet...

So I decided to upload it to the background with base64


<input type="file" id="uploadPic" name="file">
<label for="uploadPic" id="fileBtn">
+
<img class="showPic" src="" />
</label>
<span class="tip"> Please upload the picture, the size is in 2M Within <br/>( The picture type can be jpg,jepg,png,gif,bmp)<br/> The recommended picture ratio is 640*400</span>
<input type="text" name="turnUrl" class="turnUrl">
<canvas id="uploadImg" style="display:none"></canvas>

The structure is similar to the original, except for one more canvas


$("#uploadPic").on('change', function(event) {
event.preventDefault();
console.log($(this)[0].files);
var file = $(this)[0].files[0];
if(file.size>2097152){
alert(" Please upload pictures less than 2M");
return false;
} if (!/image\/\w+/.test(file.type)) {
alert(" The file must be a picture! ");
return false;
}
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) {
createCanvas(this.result);
}
});
function createCanvas(src) {
var canvas = document.getElementById("uploadImg");
var cxt = canvas.getContext('2d');
canvas.width = 640;
canvas.height = 400;
var img = new Image();
img.src = src;
img.onload = function() {
// var w=img.width;
// var h=img.height;
// canvas.width= w;
// canvas.height=h;
cxt.drawImage(img, 0, 0,640,400);
//cxt.drawImage(img, 0, 0);
$(".showPic").show().attr('src', canvas.toDataURL("image/jpeg", 0.9));
$.ajax({
url: "/front/uploadByBase64.do",
type: "POST",
data: {
"imgStr": canvas.toDataURL("image/jpeg", 0.9).split(',')[1]
},
success: function(data) {
console.log(data);
$(".showPic").show().attr('data-url',"/"+ data.url);
}
});
}
}

1. First, use the information of file file of input to judge the file size file. size and whether the file is picture file. type

2. Obtain base64 data of this picture through FileReader interface of html5

3. Pass this base64 into canvas as src of a picture. At this time, you can set the resolution of the picture to ensure that all uploaded pictures have the resolution of Unified 1. Of course, you can also follow the original size of the picture.

4. Before ajax, display the processed base64 directly (so that users can immediately see their uploaded pictures), and then transfer canvas. toDataURL ("image/jpeg", 0.9). split (',') [1] (type is image/jpeg, you can use the second parameter to set the image quality) to the corresponding interface in the background

5. Bind the url returned from the background to the data-url attribute of the picture, and get this data-url when ajax submits the whole form, so that users can see it as soon as possible, while url is still in the process of ajax to the background

Postscript: Both schemes have a problem, which will upload many redundant pictures to the backstage. However, colleagues in the background seem to have no problem.

The actual effect is as follows: http://www.qqchou.org/qqcweb/pages/photoIframe.html


Related articles: