이 문제는 이미지 파일을 업로드할 때 배경 크기를 2MB로 제한하지만, 사진을 찍기 위해 카메라를 켜면 사용자 경험과 기능 요구 사항에 영향을 주지 않기 위해 1분마다 2MB를 초과한다는 사실에서 비롯됩니다. 프런트엔드는 크기를 압축한 다음 무대 뒤에서 업로드해야 합니다.
아이디어 분석많은 정보를 검색한 결과 캔버스만이 이미지를 압축할 수 있다는 것을 알았습니다.
원리는 대략 다음과 같습니다. 1. 먼저 이미지의 파일 파일을 baseURL로 변환합니다. 2. 파일을 받을 이미지 태그를 생성하고 이미지의 너비, 높이, 비율을 가져옵니다. 3. 캔버스를 생성하고 캔버스 크기를 설정합니다. 4. 캔버스에 그림을 그립니다. 5. 캔버스를 압축하고 새 baseURL을 얻습니다. 6. baseURL을 다시 파일로 변환합니다.
전제의 기능 파일 파일을 base64로 변환/*** @param {binary file stream} file * @param {callback function, return base64} fn */functionchangeFileToBaseURL(file,fn){ // 읽기 파일 객체 생성 var fileReader = new FileReader(); file이 정의되지 않은 경우 null을 반환합니다. if(file == undefine) return fn(null); // 파일을 읽습니다. 결과는 base64비트입니다. fileReader.readAsDataURL(file); fileReader.onload = function(){ // base64 읽기 var imgBase64Data = this.result(imgBase64Data) } }base64를 파일 스트림으로 변환
/** * base64를 파일로 변환 * @param {baseURL} dataurl * @param {file name} filename * @return {file bin stream}*/function dataURLtoFile(dataurl, filename) { var arr = dataurl.split(' , '), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n) } return new File([u8arr], filename, {type:mime});압축방식
/*** 캔버스 압축 이미지* @param {parameter obj} param * @param {file Binary Stream} param.file 필수* @param {대상 압축 크기} param.targetSize가 초기 할당을 통과하지 못함 -1* @param {output 이미지 너비} param.width는 초기 할당 값 -1을 전달하지 않으며, 비례 스케일링을 위한 높이를 전달하지 않습니다.* @param {출력 이미지 이름} param.fileName은 초기 할당 값을 전달하지 않습니다. 이미지* @param {압축 이미지 정도 } param.quality는 초기 할당 값 0.92를 전달하지 않습니다. 값 범위 0~1* @param {콜백 함수} param.succ 필수 */function pressImg(param){ //콜백 함수가 없으면 실행되지 않습니다. if(param && param.succ){ //If 파일이 정의되지 않은 경우 null을 반환합니다. if(param.file == undefine) return param.succ(null); //파라미터에 초기값을 첨부합니다. param.targetSize = param.hasOwnProperty(targetSize)? param.targetSize : -1; param.width = param.hasOwnProperty(폭) ? param.fileName = param.hasOwnProperty(fileName) ? param.quality = param.hasOwnProperty( quality) ? param.quality : 0.92; var _this = this; // 파일 형식 가져오기 = param.file.type; // console.log(fileType) //image/jpeg if(fileType.indexOf(image) == -1){ console.log('이미지 파일을 선택하세요^_^'); return param.succ(null); } //현재 크기가 대상 크기보다 작으면 직접 출력 var size = param.file.size; if(param.targetSize > size){ return param.succ(param.file ) } / / 파일 파일을 읽고 결과는 base64입니다.changeFileToBaseURL(param.file,function(base64){ if(base64){ var image = new Image(); image.src = base64; image.onload = function(){ // Get 가로 세로 비율 var scale = this.width / this.height; // console.log(scale); //캔버스 만들기 var canvas = document.createElement('canvas'); //컨텍스트 가져오기 var context = canvas.getContext('2d'); //압축된 이미지 너비를 가져옵니다. 너비가 -1이면 기본 원본 이미지 너비가 canvas.width = param.width == -1입니까? width : param.width; //압축된 이미지 높이를 가져옵니다. 너비가 -1인 경우 기본 원본 이미지 높이는 canvas.height = param.width == -1입니다. parseInt(param.width / scale); //캔버스에 이미지를 그립니다. context.drawImage(image, 0, 0, canvas.width, canvas.height); //이미지를 압축하고 새로운 base64Url을 얻습니다. var newImageData = canvas . toDataURL(fileType,param.quality); //base64를 파일 스트림으로 변환 var resultFile = dataURLtoFile(newImageData,param.fileName); //targetSize가 제한되어 있고 압축된 이미지 크기가 대상 크기보다 큰 경우 오류가 발생합니다. if(param.targetSize != -1 && param.targetSize < resultFile.size ){ console .log(이미지 업로드 크기가 너무 큽니다. 다시 업로드하세요^_^); //파일 스트림 반환 param.succ(resultFile) } } } });방법 사용법
파일 크기는 바이트 단위이므로 필요한 크기를 바이트로 변환해야 합니다. 1바이트는 1바이트는 1B, 1KB = 1024B, 1MB = 1024 * 1024B
<입력 유형=파일 ID=fileImg 클래스=fileImg/>
//이미지 파일 업로드 URL 가져오기$(#fileImg).on('change',function(){ pressImg({ file:this.files[0], targetSize:2 * 1024 * 1024, 품질:0.5, 너비:600 , succ:function(resultFile){ //null이 아니면 압축에 성공한 것입니다. if(resultFile){ //TODO } } })});문제 요약 이미지 압축 수준
이미지의 압축 정도는 판단하기가 쉽지 않으므로 여러 번 시도해 보고 수요자의 요구 사항에 따라 조정할 수 있습니다. 대상 이미지의 크기와 해상도를 변경하면 이미지 압축 정도가 변경될 수 있습니다.
원래 나는 이미지 크기가 기대치를 충족할 때까지 이미지를 압축하는 재귀적 프로세스를 수행하고 싶었습니다.나중에 알아낸
iOS가 사진을 찍기 위해 시스템 카메라를 호출하면 시계 반대 방향으로 90도 회전하기 때문입니다. 이미지를 압축해서 배경으로 보낸 후 이미지의 EXIF 정보의 촬영방향이 없어져 iOS에서 업로드한 이미지가 반시계방향으로 90도 회전되는 현상을 발견했습니다. Android에서는 이 문제를 발견한 적이 없습니다.
현재는 base64를 파일파일로 변환하면서 없어졌다는 의혹이 일각에서 나오고 있다. 확인 후 여기에 추가 지침이 제공됩니다.
@version1.0-2019-8-2-"캔버스를 사용하여 이미지 크기 압축" 만들기
©burning_윤치치
위 내용은 이 기사의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다. 또한 모든 분들이 VeVb Wulin Network를 지지해 주시길 바랍니다.