JS-将图像对象转换为 jpeg 文件
JS-Convert an Image object to a jpeg file
所以,我有一个用于上传图片的用户输入。这是一个简单的例子:
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
console.log (img);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
<input type="file" onchange="handleImage(event)"><br>
如您所见,我在 console
上显示了一个 Image ()
。我想把这个 Image
转换成 jpg 文件。
我知道如何获取图片的像素,但是将它发送到服务器是完全疯狂的:它太大了!
我也尝试访问存储在计算机中的jpg文件,但没有任何结果。
我发现的唯一方法是像这样用 form
发送它:
<form action="anything.php" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload" id="fileToUpload">
</form>
在PHP中:
$_FILES["fileToUpload"]["tmp_name"]
为什么不用 JS?
我的最终目标是发送带有 AJAX 的 jpg 文件。
如果您有任何问题,请告诉我。
JavaScript客户端无法保存文件。
您有多种选择:
- 在
<canvas>
元素上渲染图像。这样就可以通过右键单击->保存图像 来保存
- 将图像插入为
<img>
元素。这样就可以通过右键单击->保存图像 来保存
- 将图像数据作为base64 字符串发送到服务器。在那里进行处理
- 使用 PHP 或 Node.js 等服务器端语言保存文件
长话短说,您必须使用一些服务器端逻辑将文件保存在磁盘上
最简单的方法是使用 canvas 元素,然后调用允许用户select 保存图像的下载操作。
你提到图像很大,但没有提到多少 - 请注意,使用 canvas 当图像源开始接触 8k 像素区域时,你也会 运行 受到限制尺寸。
一个简化的例子(IE 将需要 toBlob()
的 polyfill)。:
- 通过输入加载图像源
- 通过
URL.createObjectURL()
直接使用文件 blob 作为图像源
- 加载后,创建一个临时的canvas,设置canvas size = image size 并在image中绘制
- 使用
toBlob()
(内存和性能更高效,不需要转码to/from Base64)获得Blob
.
- 我们会将
Blob
转换为 File
(一个子集对象,它将引用相同的内存)因此我们还可以提供一个文件名以及(重要!)一个 二进制 mime 类型.
由于最后一步的 mime 类型是二进制的,因此浏览器将调用“另存为”对话框。
document.querySelector("input").onchange = function() {
var img = new Image;
img.onload = convert;
img.src = URL.createObjectURL(this.files[0]);
};
function convert() {
URL.revokeObjectURL(this.src); // free up memory
var c = document.createElement("canvas"), // create a temp. canvas
ctx = c.getContext("2d");
c.width = this.width; // set size = image, draw
c.height = this.height;
ctx.drawImage(this, 0, 0);
// convert to File object, NOTE: we're using binary mime-type for the final Blob/File
c.toBlob(function(blob) {
var file = new File([blob], "MyJPEG.jpg", {type: "application/octet-stream"});
window.location = URL.createObjectURL(file);
}, "image/jpeg", 0.75); // mime=JPEG, quality=0.75
}
// NOTE: toBlob() is not supported in IE, use a polyfill for IE.
<label>Select image to convert: <input type=file></label>
更新:如果您只是在寻找新创建的 JPEG 的字符串(base-64 编码)版本,只需使用 toDataURL()
而不是 toBlob()
:
document.querySelector("input").onchange = function() {
var img = new Image;
img.onload = convert;
img.src = URL.createObjectURL(this.files[0]);
};
function convert() {
URL.revokeObjectURL(this.src); // free up memory
var c = document.createElement("canvas"), // create a temp. canvas
ctx = c.getContext("2d");
c.width = this.width; // set size = image, draw
c.height = this.height;
ctx.drawImage(this, 0, 0);
// convert to File object, NOTE: we're using binary mime-type for the final Blob/File
var jpeg = c.toDataURL("image/jpeg", 0.75); // mime=JPEG, quality=0.75
console.log(jpeg.length)
}
<label>Select image to convert: <input type=file></label>
所以,我有一个用于上传图片的用户输入。这是一个简单的例子:
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
console.log (img);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
<input type="file" onchange="handleImage(event)"><br>
如您所见,我在 console
上显示了一个 Image ()
。我想把这个 Image
转换成 jpg 文件。
我知道如何获取图片的像素,但是将它发送到服务器是完全疯狂的:它太大了!
我也尝试访问存储在计算机中的jpg文件,但没有任何结果。
我发现的唯一方法是像这样用 form
发送它:
<form action="anything.php" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload" id="fileToUpload">
</form>
在PHP中:
$_FILES["fileToUpload"]["tmp_name"]
为什么不用 JS?
我的最终目标是发送带有 AJAX 的 jpg 文件。
如果您有任何问题,请告诉我。
JavaScript客户端无法保存文件。 您有多种选择:
- 在
<canvas>
元素上渲染图像。这样就可以通过右键单击->保存图像 来保存
- 将图像插入为
<img>
元素。这样就可以通过右键单击->保存图像 来保存
- 将图像数据作为base64 字符串发送到服务器。在那里进行处理
- 使用 PHP 或 Node.js 等服务器端语言保存文件
长话短说,您必须使用一些服务器端逻辑将文件保存在磁盘上
最简单的方法是使用 canvas 元素,然后调用允许用户select 保存图像的下载操作。
你提到图像很大,但没有提到多少 - 请注意,使用 canvas 当图像源开始接触 8k 像素区域时,你也会 运行 受到限制尺寸。
一个简化的例子(IE 将需要 toBlob()
的 polyfill)。:
- 通过输入加载图像源
- 通过
URL.createObjectURL()
直接使用文件 blob 作为图像源
- 加载后,创建一个临时的canvas,设置canvas size = image size 并在image中绘制
- 使用
toBlob()
(内存和性能更高效,不需要转码to/from Base64)获得Blob
. - 我们会将
Blob
转换为File
(一个子集对象,它将引用相同的内存)因此我们还可以提供一个文件名以及(重要!)一个 二进制 mime 类型.
由于最后一步的 mime 类型是二进制的,因此浏览器将调用“另存为”对话框。
document.querySelector("input").onchange = function() {
var img = new Image;
img.onload = convert;
img.src = URL.createObjectURL(this.files[0]);
};
function convert() {
URL.revokeObjectURL(this.src); // free up memory
var c = document.createElement("canvas"), // create a temp. canvas
ctx = c.getContext("2d");
c.width = this.width; // set size = image, draw
c.height = this.height;
ctx.drawImage(this, 0, 0);
// convert to File object, NOTE: we're using binary mime-type for the final Blob/File
c.toBlob(function(blob) {
var file = new File([blob], "MyJPEG.jpg", {type: "application/octet-stream"});
window.location = URL.createObjectURL(file);
}, "image/jpeg", 0.75); // mime=JPEG, quality=0.75
}
// NOTE: toBlob() is not supported in IE, use a polyfill for IE.
<label>Select image to convert: <input type=file></label>
更新:如果您只是在寻找新创建的 JPEG 的字符串(base-64 编码)版本,只需使用 toDataURL()
而不是 toBlob()
:
document.querySelector("input").onchange = function() {
var img = new Image;
img.onload = convert;
img.src = URL.createObjectURL(this.files[0]);
};
function convert() {
URL.revokeObjectURL(this.src); // free up memory
var c = document.createElement("canvas"), // create a temp. canvas
ctx = c.getContext("2d");
c.width = this.width; // set size = image, draw
c.height = this.height;
ctx.drawImage(this, 0, 0);
// convert to File object, NOTE: we're using binary mime-type for the final Blob/File
var jpeg = c.toDataURL("image/jpeg", 0.75); // mime=JPEG, quality=0.75
console.log(jpeg.length)
}
<label>Select image to convert: <input type=file></label>