将Base64图像转换为JPEG

3

无法将使用网络摄像机捕获的base64图像转换为jpeg格式以进行上传。

以下捕获/显示照片有效(请注意,我正在使用webcam.min.js(返回base64),而不是webcam.js(返回jpeg但依赖Flash)-

function take_snapshot() {
Webcam.snap( function(data_uri) {
// display results in page
document.getElementById('upload_results').innerHTML = 
'<img id="imageprev" src="'+data_uri+'"/>';
} );
}

我尝试了以下方法,可能已经将Base64图像转换为Blob格式 -
function saveSnap(){
var base64image = document.getElementById("imageprev").src;
alert(base64image)
                                
                                                               
    // convert base64 to raw binary data held in a string
    var byteString = atob(base64image.split(',')[1]);
    // separate out the mime component
    var mimeString = base64image.split(',')[0].split(':')[1].split(';')[0];
    // write the bytes of the string to an ArrayBuffer
    var ab = new ArrayBuffer(byteString.length);
    var dw = new DataView(ab);
    for(var i = 0; i < byteString.length; i++) {
    dw.setUint8(i, byteString.charCodeAt(i));
                                                                    alert("arrived here");
                                                                    
    // write the ArrayBuffer to a blob, and you're done
    return new Blob([ab], {type: mimeString});
    }

这个并没有实际作用,只会停止jsp的执行

let image = new Image();
image.src = base64image;
document.body.appendChild(image);

我该如何获取/查看/提取实际的JPEG文件,以便上传它(它必须是像数字.jpeg这样的东西)

JDK6 / JavaScript(请勿使用PHP)

欢迎任何想法。

祝好, Ralph


1
这个回答解决了你的问题吗?如何在JavaScript中将DataURL转换为文件对象? - Njuguna Mureithi
webcam.js并不返回数据URL(尽管我一直在使用它,但是webcam.js会退回到使用Flash),我不得不切换到返回base64字符串的webcam.min.js。 - Ralph
经过一番尝试,我可能会将base64转换为blob,但我不知道如何将blob转换为jpeg,甚至不确定是否应该这样做(我需要上传到服务器的jpeg格式)。 - Ralph
@Ralph 如果你将base64编码的图像转换为“blob”,那么该“blob”包含/是二进制JPEG图像。 - Marc
谢谢Marc,我该如何从blob中获取/查看jpeg(文件扩展名等)?我需要实际的jpeg文件,然后才能上传。 - Ralph
显示剩余4条评论
3个回答

2
创建一个图片对象并将base64作为其源。
let image = new Image();
image.src = 'data:image/png;base64,iVBORw0K...';
document.body.appendChild(image);

var aFilePartss = [image];
var oMyBlob = new Blob(aFileParts, {type : 'image/png'});
// window.open(URL.createObjectURL(oMyBlob));

var fd = new FormData();
fd.append('data', oMyBlob);
$.ajax({
    type: 'POST',
    url: '/upload.php',
    data: fd,
}).done(function(data) {
    console.log(data);
});

谢谢Mohiuddin,如果我的base64image名称是'base64image',请详细说明在您的示例代码中我需要如何引用它以及输出将是什么。 - Ralph
image.src = base64image,然后您将在“image”变量中获得原始图像。它将在您的HTML页面上创建一个原始img标签。您需要制作并下载压缩的PNG文件吗? - Mohiuddin Khan
我需要一个 JPEG 文件,这样我就可以上传真正的照片到服务器端了。 - Ralph
再次感谢,窗口会打开显示照片。我该如何在代码中引用它,以便我的服务器可以上传它(即一个实际的 JPEG 文件)。我只需要引用 oMyBlob 吗? - Ralph
你可以通过Ajax请求上传Blob文件,已更新答案。 - Mohiuddin Khan
谢谢,但我不想使用PHP,我在“更新资产”JSP中有另一个函数,可以上传JPEG。我似乎一无所获,这真是令人沮丧。 - Ralph

1

将base64转换为文件(image/jpeg)的示例代码:

async base64ToFile(base64) {
  const res = await fetch(base64)
  const buf = await res.arrayBuffer()
  const file = new File([buf], "capture_camera.jpeg", {
    type: 'image/jpeg',
  })
  return file;
};

1
这里是你需要将其转换为blob并上传的基础知识。

const MOCK_DATA_URL = `data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEVBMTczNDg3QzA5MTFFNjk3ODM5NjQyRjE2RjA3QTkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEVBMTczNDk3QzA5MTFFNjk3ODM5NjQyRjE2RjA3QTkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowRUExNzM0NjdDMDkxMUU2OTc4Mzk2NDJGMTZGMDdBOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowRUExNzM0NzdDMDkxMUU2OTc4Mzk2NDJGMTZGMDdBOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjjUmssAAAGASURBVHjatJaxTsMwEIbpIzDA6FaMMPYJkDKzVYU+QFeEGPIKfYU8AETkCYI6wANkZQwIKRNDB1hA0Jrf0rk6WXZ8BvWkb4kv99vn89kDrfVexBSYgVNwDA7AN+jAK3gEd+AlGMGIBFDgFvzouK3JV/lihQTOwLtOtw9wIRG5pJn91Tbgqk9kSk7GViADrTD4HCyZ0NQnomi51sb0fUyCMQEbp2WpU67IjfNjwcYyoUDhjJVcZBjYBy40j4wXgaobWoe8Z6Y80CJBwFpunepIzt2AUgFjtXXshNXjVmMh+K+zzp/CMs0CqeuzrxSRpbOKfdCkiMTS1VBQ41uxMyQR2qbrXiiwYN3ACh1FDmsdK2Eu4J6Tlo31dYVtCY88h5ELZIJJ+IRMzBHfyJINrigNkt5VsRiub9nXICdsYyVd2NcVvA3ScE5t2rb5JuEeyZnAhmLt9NK63vX1O5Pe8XaPSuGq1uTrfUgMEp9EJ+CQvr+BJ/AAKvAcCiAR+bf9CjAAluzmdX4AEIIAAAAASUVORK5CYII=`

function takeSnapshotThenUpload() {
  //get datauri
  let blob = convertToBlob(MOCK_DATA_URL)
  return uploadFile(blob)

}



function convertToBlob(base64image) {
  // convert base64 to raw binary data held in a string
  var byteString = atob(base64image.split(',')[1]);
  // separate out the mime component
  var mimeString = base64image.split(',')[0].split(':')[1].split(';')[0];
  // write the bytes of the string to an ArrayBuffer
  var ab = new ArrayBuffer(byteString.length);
  var dw = new DataView(ab);
  for (var i = 0; i < byteString.length; i++) {
    dw.setUint8(i, byteString.charCodeAt(i));
    alert("arrived here");

    // write the ArrayBuffer to a blob, and you're done
    return new Blob([ab], {
      type: mimeString
    });
  }
}

function uploadFile(blob) {
  const formData = new FormData()
  formData.append('cancel.jpeg', blob)

  fetch('/saveImage', {
      method: 'POST',
      body: formData
    })
    .then(response => response.json())
    .then(data => {
      console.log(data)
    })
    .catch(error => {
      console.error(error)
    })
}
<button onclick="takeSnapshotThenUpload()">Take screenshot then upload</button>

Remember to fix your takeSnapshotThenUpload to something like:

<script src="webcam.js"></script>

<div id="my_camera" style="width:320px; height:240px;"></div>
<div id="my_result"></div>

<script language="JavaScript">
    Webcam.attach( '#my_camera' );
    
    function take_snapshot() {
        Webcam.snap( function(data_uri) {
            takeSnapshotThenUpload(data_uri)
        } );
    }
</script>

<a href="javascript:void(take_snapshot())">Take Snapshot</a>

再次感谢,我会花些时间修复我的代码并分析你的。这节省了我许多周来试图解决这个问题时的一些抓狂。当 Flash 还存在时,生活要简单得多。 - Ralph
顺便问一下,您知道是否可以使用image_url(在webcam.js中),并以某种方式强制它不使用Flash,因为这将避免使用webcam.min.js及其所有缺陷? - Ralph
我对webcam.js不是很熟悉。你试过用HTML5代替Flash吗?看起来好像不需要Flash https://caniuse.com/?search=webcam - Njuguna Mureithi
webcam.js是HTML5,但无论网站是否使用https都会使用Flash。其他任何方法(例如使用datauri,然后将base64转换为blob,再通过一些其他魔法来获取jpeg),在我看来都是荒谬的。我不相信捕获图像并输出jpeg可以那么复杂。当使用webcam.js时,只需要5行代码即可完成。 - Ralph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接