直播原始碼網站,js處理圖片變形、方向、壓縮等

zhibo系統開發發表於2021-12-15

直播原始碼網站,js處理圖片變形、方向、壓縮等實現的相關程式碼

//檢查圖片是否有被壓扁,如果有,返回比率
//http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios
function detectVerticalSquash(img) {
  // 拍照在IOS7或以下的機型會出現照片被壓扁的bug
  var data;
  var ih = img.naturalHeight;
  var canvas = document.createElement('canvas');
  canvas.width = 1;
  canvas.height = ih;
  var ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  try {
    data = ctx.getImageData(0, 0, 1, ih).data;
  } catch (err) {
    console.log('Cannot check verticalSquash: CORS?');
    return 1;
  }
  var sy = 0;
  var ey = ih;
  var py = ih;
  while (py > sy) {
    var alpha = data[(py - 1) * 4 + 3];
    if (alpha === 0) {
      ey = py;
    } else {
      sy = py;
    }
    py = (ey + sy) >> 1; // py = parseInt((ey + sy) / 2)
  }
  var ratio = py / ih;
  return ratio === 0 ? 1 : ratio;
}
//
function dataURItoBuffer(dataURI) {
  var byteString = atob(dataURI.split(',')[1]);
  var buffer = new ArrayBuffer(byteString.length);
  var view = new Uint8Array(buffer);
  for (var i = 0; i < byteString.length; i++) {
    view[i] = byteString.charCodeAt(i);
  }
  return buffer;
}
function dataURItoBlob(dataURI) {
  var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
  var buffer = dataURItoBuffer(dataURI);
  return new Blob([buffer], { type: mimeString });
}
//獲取圖片的orientation
//
function getOrientation(buffer) {
  var view = new DataView(buffer);
  if (view.getUint16(0, false) != 0xffd8) return -2;
  var length = view.byteLength,
    offset = 2;
  while (offset < length) {
    var marker = view.getUint16(offset, false);
    offset += 2;
    if (marker == 0xffe1) {
      if (view.getUint32((offset += 2), false) != 0x45786966) return -1;
      var little = view.getUint16((offset += 6), false) == 0x4949;
      offset += view.getUint32(offset + 4, little);
      var tags = view.getUint16(offset, little);
      offset += 2;
      for (var i = 0; i < tags; i++)
        if (view.getUint16(offset + i * 12, little) == 0x0112)
          return view.getUint16(offset + i * 12 + 8, little);
    } else if ((marker & 0xff00) != 0xff00) break;
    else offset += view.getUint16(offset, false);
  }
  return -1;
}
 //修正拍照時圖片的方向
 //
function orientationHelper(canvas, ctx, orientation) {
  const w = canvas.width,
    h = canvas.height;
  if (orientation > 4) {
    canvas.width = h;
    canvas.height = w;
  }
  switch (orientation) {
    case 2:
      ctx.translate(w, 0);
      ctx.scale(-1, 1);
      break;
    case 3:
      ctx.translate(w, h);
      ctx.rotate(Math.PI);
      break;
    case 4:
      ctx.translate(0, h);
      ctx.scale(1, -1);
      break;
    case 5:
      ctx.rotate(0.5 * Math.PI);
      ctx.scale(1, -1);
      break;
    case 6:
      ctx.rotate(0.5 * Math.PI);
      ctx.translate(0, -h);
      break;
    case 7:
      ctx.rotate(0.5 * Math.PI);
      ctx.translate(w, -h);
      ctx.scale(-1, 1);
      break;
    case 8:
      ctx.rotate(-0.5 * Math.PI);
      ctx.translate(-w, 0);
      break;
  }
}
// canvas 壓縮圖片
export function compress(file, options, callback) {
  const reader = new FileReader();
  reader.onload = function (evt) {
    if (options.compress === false) {
      // 不啟用壓縮 & base64上傳 的分支,不做任何處理,直接返回檔案的base64編碼
      file.base64 = evt.target.result;
      callback(file);
      return;
    }
    // 啟用壓縮的分支
    const img = new Image();
    img.onload = function () {
      const ratio = detectVerticalSquash(img);
      const orientation = getOrientation(dataURItoBuffer(img.src));
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      const maxW = options.compress.width;
      const maxH = options.compress.height;
      let w = img.width;
      let h = img.height;
      let dataURL;
      if (w < h && h > maxH) {
        w = parseInt((maxH * img.width) / img.height);
        h = maxH;
      } else if (w >= h && w > maxW) {
        h = parseInt((maxW * img.height) / img.width);
        w = maxW;
      }
      canvas.width = w;
      canvas.height = h;
      if (orientation > 0) {
        orientationHelper(canvas, ctx, orientation);
      }
      ctx.drawImage(img, 0, 0, w, h / ratio);
      if (/image\/jpeg/.test(file.type) || /image\/jpg/.test(file.type)) {
        dataURL = canvas.toDataURL('image/jpeg', options.compress.quality);
      } else {
        dataURL = canvas.toDataURL(file.type);
      }
      if (options.type == 'file') {
        if (/;base64,null/.test(dataURL) || /;base64,$/.test(dataURL)) {
          // 壓縮出錯,以檔案方式上傳的,採用原檔案上傳
          console.warn(
            'Compress fail, dataURL is ' +
              dataURL +
              '. Next will use origin file to upload.'
          );
          callback(file);
        } else {
          let blob = dataURItoBlob(dataURL);
          blob.id = file.id;
          blob.name = file.name;
          blob.lastModified = file.lastModified;
          blob.lastModifiedDate = file.lastModifiedDate;
          callback(blob);
        }
      } else {
        if (/;base64,null/.test(dataURL) || /;base64,$/.test(dataURL)) {
          // 壓縮失敗,以base64上傳的,直接報錯不上傳
          options.onError(
            file,
            new Error('Compress fail, dataURL is ' + dataURL + '.')
          );
          callback();
        } else {
          file.base64 = dataURL;
          callback(file);
        }
      }
    };
    img.src = evt.target.result;
  };
  reader.readAsDataURL(file);
}
// 補全圖片base64頭部
export function completePictureBase64(suffix,file) {
  if(suffix === 'png') {
    return 'data:image/png;base64,' + file
  }else {
    return 'data:image/jpeg;base64,' + file
  }
}


以上就是 直播原始碼網站,js處理圖片變形、方向、壓縮等實現的相關程式碼,更多內容歡迎關注之後的文章


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2847869/,如需轉載,請註明出處,否則將追究法律責任。

相關文章