Javascript 如何将PNG转换为JPG(客户端),然后再转换回PNG(服务器端),从而保留完整和半透明的像素?

Javascript 如何将PNG转换为JPG(客户端),然后再转换回PNG(服务器端),从而保留完整和半透明的像素?,javascript,html,canvas,png,jpeg,Javascript,Html,Canvas,Png,Jpeg,我正在用HTML5+JS编写一个应用程序,在某个时候我需要上传一个元素的内容,该元素上绘制了一些PNG文件。所以我在做: $('#img').val(canvasElement.toDataURL()); 如您所见,我没有为toDataURL函数提供参数,因此提取的图像将采用PNG格式#img是一种文本输入(具有名称属性“img”),稍后用于将从画布提取的图像的base64表示上载到服务器。我使用AJAX实现了这一点,请求一个包含以下代码的PHP文件: $data = explode(','

我正在用HTML5+JS编写一个应用程序,在某个时候我需要上传一个
元素的内容,该元素上绘制了一些PNG文件。所以我在做:

$('#img').val(canvasElement.toDataURL()); 
如您所见,我没有为toDataURL函数提供参数,因此提取的图像将采用PNG格式
#img
是一种文本输入(具有名称属性“img”),稍后用于将从画布提取的图像的base64表示上载到服务器。我使用AJAX实现了这一点,请求一个包含以下代码的PHP文件:

$data = explode(',', $_POST['img']);
$imgdata = base64_decode($data[1]);

$ifp = fopen('superGraphicFile.png', "wb");
fwrite($ifp, $imgdata); 
fclose($ifp);
这是可行的,但不幸的是,300x600 PNG文件足以使AJAX请求持续很长时间(比如20秒),因为此时文件大小约为400KB。就我而言,所需的时间是无法接受的

我想知道如何减少发送到服务器的数据量,我认为以JPG格式发送会很酷,因为我们可以指定从画布提取的JPEG图像的质量。例如,调用
toDataURL('image/jpeg',0.7)
,使文件比不带参数调用文件小10倍。但是,我必须保留原始PNG文件中关于透明度的信息,因为JPG无法做到这一点,所以我想发明一些方法在服务器端重新创建原始PNG

首先,我考虑用一些特定的颜色填充原始PNG中的所有透明像素,将其转换为JPG,发送到服务器,并用透明像素替换所有具有该颜色的像素。但是,这可能不起作用,因为我还需要保留原始图像中的半透明像素。也许有某种方法可以从原始图像中提取alpha通道,将其作为另一个JPG发送到服务器,并将其作为服务器端的掩码应用,以这种方式重新创建原始PNG?或者我错过了其他的解决方案

我提前感谢你的建议


编辑:我写的20秒可能是我的互联网连接出现了一些问题,因为我没有更改任何内容,现在传输400 kb的数据大约需要一秒钟。但我仍然认为,将服务器资源节省10%并使应用程序运行得更快将是一件很酷的事情。

我担心,您试图用肮脏的变通方法来解决您的问题(无意冒犯)。将PNG转换为JPEG并返回PNG将始终是一种有损转换(包括丢失alpha通道),并且将比仅发送原始文件消耗更多的CPU周期

最好的方法可能是查看代码内部并尝试以某种方式对其进行优化。在当今的网络和个人电脑中,传输/处理400kB的数据不应花费20秒。此外,在某些情况下,JPEG可能比PNG大得多-例如,窗口的屏幕截图在PNG中为141kB,但在JPEG中为245kB

另一方面,如果使用有损格式确实更好,那么您可以看看这个。我发现,还有其他一些人支持透明度。 也许您可以尝试使用tiff图像格式,它可以包括图像数据和alpha通道(希望使用JPEG压缩)。唯一的问题是,我只知道一款浏览器支持TIFF开箱即用(Safari)

最好的选择可能是转换成GIF格式。它是无损的,并将保持透明度。当然,没有半透明度和有限的颜色


另一种选择是使用它,因为它具有更高的压缩比和更低的质量损失,并且还支持alpha通道。Safari同样支持它,但Firefox需要一个插件。我记得几年前,我有一个JPEG2K的M$InternetExplorer插件。我不知道还有其他支持JPEG 2k的“主流”浏览器。

JS可以生成第二个包含alpha通道的JPG文件,作为简单的黑白图像吗?400kb不需要20秒就可以完成transfer@3rror404取决于你的关系,是吗?嗯,是的。不过,这将是一个非常缓慢的连接。我认为,也许一些图像处理运行缓慢,而不仅仅是传输为什么不显示一些进度条,而不是创建另一个图像格式呢?这肯定是一个有损的转换(虽然损失非常明显),但在这种情况下,这将是一个完美的解决方案。忘记这20秒吧,这可能是我的互联网连接暂时的问题。关注这个事实:用另一个包含alpha频道的JPG以JPG的形式发送PNG图像,可以节省10%的服务器资源,并使应用程序速度更快。这不值得吗?我真的很有可能增加原始PNG文件的压缩(甚至丢失一些质量),但它是不可能的。还要考虑,PNG比JPEG本身有很多更好的压缩比。好吧,我不是说照片,JPEG真的好得多。但是当你有一个alpha通道时,它几乎肯定不是一张照片。因此,PNG的压缩比JPEG要好得多(如果您不使用5%的质量,并且不丢失其中的所有图像信息)。;-)