在客户端(javascript)从html转换图像为jpg格式

3
我有一个html表单,用户可以插入一张图片(输入)。我的用户可能不是高级用户,所以他们可能想插入许多不同类型的图像格式。然而,我只想让用户发送jpg / gif / png文件。一种选择是阻止其他文件类型,但是,我想知道是否可以在客户端转换文件(我不想发送非常大的文件,并在服务器上进行转换)。因此,我能想到的唯一方法是使用javacript。

那么,有人知道如何在javascript中进行图像格式转换吗?并将此图像结果作为html:input的值放置?

谢谢!


如果不行的话,也许可以使用HTML5? - Mateu
不,HTML 5没有添加那种功能。 - Michael
8个回答

4

简而言之:不要尝试

理论上可能是可行的,但我强烈建议不要这样做。可以创建一个JavaScript Img元素,引用用户输入的URL。然后可以在HTML5画布中绘制此图像。

然后可以手动访问画布上的数据并分析/转换图像到适当的格式。然后可能将其Base64编码或URL编码发送到服务器,服务器可以将图像返回给客户端。

当然,这完全是疯狂的,不应尝试。这个解决方案需要在JavaScript中实现JPG压缩,虽然从技术上讲是可能的,但由于浏览器限制(例如速度),可能不可行。


我同意。这可能是现在唯一的方法,但肯定不是最容易也不是最快的方法。 - gion_13
如果文件无法通过URL /在线方式访问(如果它们正在上传),则这是不可实现的,因此仍然需要使用服务器端解决方案。 - Michael
@Mikaveli,我必须承认,当我提出这个答案时,我并没有真正考虑到可实现性。 - Exelian

2

不可能。JavaScript无法操作二进制内容。


2
你可以使用Java小程序(类似于Facebook照片上传小程序,用于在上传前预先准备/调整图像大小),这是你可用的不多的选项之一。
基本上,在客户端执行转换将会非常困难,但是它是可能的(使用浏览器插件)。仅依靠JavaScript是不可能的。即使是可能的,由于各个浏览器实现的差异,这也是危险的。其他解决方案不会零足迹(用户必须在他们的计算机上安装依赖项)。
最好和最可靠的选择是在服务器端执行转换(如果你熟悉Java,则使用Apache Batik),使用你有的并熟悉的任何技术。

2

1

根本不可能。

没有客户端JavaScript支持进行图像处理。

您可以使用市场上大多数流行的Web浏览器的可扩展性API,例如Internet Explorer、Firefox、Safari、Chrome或Opera,但这不是基于标准Javascript的解决方案。无论如何,这将是一个客户端解决方案,其中一些API支持文档操作,因此,也许您可以处理某些具有特定CSS类的HTML元素中的某些点击。


0

这是可能的,但不建议这样做。

首先,您需要获取 exif 数据以正确旋转来自移动设备的图像。然后,您需要验证文件类型并将其转换为可通过ajax上传的格式。为此,您需要一个可以在画布对象上处理“toDataURL”的浏览器:

function supportsToDataURL() {
    var c = document.createElement("canvas");
    var data = c.toDataURL("image/jpeg");
    return (data.indexOf("data:image/jpeg") == 0)        
}

一旦您获取了文件,我喜欢使用megapix渲染它:megapixel库

像这样监听图像的onload事件:

var img = new Image()
img.onload = function() {
    // do some stuff like rendering image to a canvas
}
var mpImg = new MegaPixImage(file);
mpImg.render(img, { quality: 1, maxWidth: 1024 });  

然后,您可以将图像写入画布:

var canvas = document.createElement('canvas'),
    ctx = canvas.getContext('2d');

canvas.width = sourceWidth;
canvas.height = sourceHeight;

ctx.drawImage(img, 0, 0, sourceWidth, sourceHeight);
var url = canvas.toDataURL();
// or if you want a specific file type
var jpeg = canvas.toDataURL("image/jpeg");
var png = canvas.toDataURL("image/png");

注意:某些版本的Android可能支持“toDataURL”,但不支持完整规范。它们可能只呈现PNG等格式。这只是在图像渲染上尝试实现跨浏览器兼容性时会遇到的众多问题之一。

相信我,我已经花了大约16个小时为移动Web应用程序制作图像裁剪和调整工具,这并不是一项容易的任务。

更好的解决方案是让用户选择一个文件,将其转换为base64并通过ajax上传。然后在服务器端进行转换,并(如果必要)向用户发送可以查看的内容。

我正在开发一个插件,以允许移动图像上传,完成后我会在这里放置链接。


0

0
现代浏览器现在提供了在浏览器中转换图像的方法,如果需要的话。以下方法可用于任何支持OffscreenCanvas和所需文件类型的浏览器:
/**
 * Convert between any image formats the browser supports
 * @param {Blob} source A Blob (or File) containing the image to convert
 * @param {string} type The MIME type of the target format
 * @returns {Promise<Blob>} The converted image
 */
async function convert(source, type) {
    let image = await createImageBitmap(source);

    let canvas = new OffscreenCanvas(image.width, image.height);
    let context = canvas.getContext("2d");
    context.drawImage(image, 0, 0);

    let result = await canvas.convertToBlob({ type });

    image.close();
    return result;
}

在不支持OffscreenCanvas的浏览器上,比如(截至2023年1月)Safari,可以使用以下方法:
/**
 * Convert between any image formats the browser supports
 * @param {Blob} source A Blob (or File) containing the image to convert
 * @param {string} type The MIME type of the target format
 * @returns {Promise<Blob>} The converted image
 */
async function convertLegacy(source, type) {
    let image = await createImageBitmap(source);

    let canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;

    let context = canvas.getContext("2d");
    context.drawImage(image, 0, 0);

    let result = await new Promise((resolve, reject) => {
        canvas.toBlob((blob) => {
            if (blob != null) {
                resolve(blob);
            } else {
                reject(new Error("Failed to convert file"));
            }
        }, type, 1);
    });

    image.close();
    return result;
}

请注意,第二种方法在WebWorker中不起作用。
如果给出了不支持的目标格式,则浏览器将默认为PNG。可能没有不支持JPEG的浏览器。

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