HTML canvas 字节数组到 java 中的图像
HTML canvas byte array to Image in java
实际图像
生成的图像
我在客户端使用 Javascript(SAP/Open-UI-5) 生成了多个图表(比如最多 14 个),我已将这些图表转换为字节数组,下面是相同
Java脚本代码
var arrCanvas = document.getElementsByTagName("canvas");
var arrImageByte = [];
for(var i=0; i<arrCanvas.length; i++){
var canvas = arrCanvas[i];
if(canvas.width!=0 && (typeof imageNames[i] != 'undefined')){
var imageDetail = {};
var uint8Array = canvas.getContext("2d").getImageData(0,0,canvas.width,canvas.height).data;
imageDetail.byteData = [].slice.call(uint8Array);
imageDetail.name = imageNames[i];
imageDetail.height = canvas.height;
imageDetail.width = canvas.width;
arrImageByte.push(imageDetail);
}
}
现在我使用 REST API 和 AJAX 调用将这些字节发送到服务器端
在下面的服务器端创建图像是我重新创建图像的代码
Java代码
int width = imageDetail.getWidth();
int height = imageDetail.getHeight();
byte[] data = imageDetail.getByteData();
String name = imageDetail.getName();
BufferedImage bufferedImage =new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// calculate array offset
final int o = (x * 3) + (y * width * 3);
// set the pixel color here we will need to convert the byte
// data to an unsigned
// value using &0xFF before passing it to the Color
// constructor
bufferedImage.setRGB(x, y, new Color(data[o + 1] & 0xFF, data[o + 2] & 0xFF, data[o + 3] & 0xFF).getRGB());
}
}
boolean result = ImageIO.write(bufferedImage, "jpg", new File(baseReportFolderLocation+name+".jpg"));
logger.info("Name "+name+" status :: "+result);
但是我的图像颜色与预期的不一样。如何重新创建与在客户端创建时颜色完全相同的图像?
我也试过下面的代码
byte[] data = imageDetail.getByteData();
String name = imageDetail.getName();
BufferedImage bImageFromConvert = ImageIO.read(new ByteArrayInputStream(data));
ImageIO.write(bImageFromConvert, "jpg", new File(baseReportFolderLocation+"New_"+name+".jpg"));
最后一行抛出异常
java.lang.IllegalArgumentException: image == null!
at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925)
at javax.imageio.ImageIO.getWriter(ImageIO.java:1592)
我遵循了您描述的代码(谢谢您,因为它帮助我分析了我面临的问题并且我遵循了类似的方法),在对我所做的 java 代码进行了以下更改之后图像与原始图像完全相同
int width = imageDetail.getWidth();
int height = imageDetail.getHeight();
byte[] data = imageDetail.getByteData();
String name = imageDetail.getName();
BufferedImage bufferedImage =new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int o = (x * 4) + (y * width * 4);
bufferedImage.setRGB(x, y, new Color(data[o] & 0xFF, data[o + 1] & 0xFF, data[o + 2] & 0xFF).getRGB());
}
}
try {
ImageIO.write(bufferedImage, "jpg", new File(PDFReportingUtil.baseReportFolderLocation+name+".jpg"));
} catch (IOException e) {
PDFReportingUtil.logger.error("Error while executing the thread "+Thread.currentThread().getName()+" ",e);
}
这是一个简单的解决方案,避免了循环和所有手动工作。!!
要求: org.apache.commons.codec.binary.Base64
class。所以将其添加到您的 classpath.
如果使用 Maven,请将以下依赖项添加到您的 pom.xml
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
如果使用 jar
作为依赖项,请在您的 lib
或 class 路径中添加以下 jar 文件。
解法:
以下是我的图像,我将使用 byte array
重新创建。
注意颜色:-
- 尺寸:50px * 20px
- 背景 - 白色
- M - 黑色
- A - 黄色
- N - 绿色
- O - 蓝色
- J - 橙色
只是为了验证不同的颜色是否正确保留。
代码
public static void main(String args[]) throws Exception {
String abs = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAUCAIAAABAqPnNAAAAAXNSR0IArs4c6QAAAARnQU1BAACx\n" +
"jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIBSURBVEhL7ZW9SgNREIXzBD5EGt8hjdhZSAqf\n" +
"QVIkkC5gZ5VSWAg2IbUQtrJZSBGDIEQhXVAIN1FCcBtZCwstx/m7u3d/VAQ1Ch4uZGZuYD/OmU1K\n" +
"8Cv1j/UZ/SEs41VKqIpndCAKajQt1QLtv1YPPTjchOOedAVYSpUBUKjvooLzPcI6v5MujxVTuQQW\n" +
"6tuoMsphJVQxAo8qFZrraA73DZhuwBUf0+EhKzwqn+6WJ3530qTitNkK9Qa1HIft+mRrh099caFj\n" +
"m6B/pm0eS6hqNXJHGATK85IJPHeIZtoA01CyiOcAwwmi0KmOBGu3PPJv+WrZvxag/bot+i98YxO8\n" +
"0Q6VwVKqQFmMhTKcYlGC99sO1mWLUI6GT9ypc5dUr8J9cihc8g2MFw7WHRxvwuEB16o0lqWyNAF9\n" +
"2NahmkM00ENRNnTMHNXZSrrbGRkmIYpV7TFfZNpcgqgUVvJ0qUhJp1SG7XGPGfCFJNjsilWw6o7Y\n" +
"OapfTmil4mVKt7kEUS6W83SL5TRcRrxM0Zy+jsonaDcJnvzqGwmKVe8kiHKw0p54uPYB/566c8P2\n" +
"yLJPxbaPE1QsOtdaxEtWlCAqweKnZ3/ZUSnaiN9BOtv6Gn6cIGnZX8Rk7f6jMqGKEkSlV/6nVZwg\n" +
"an1YNz3w2apcgqh1YYlP+N9cYBVqvSG+qV+JBfAKOyszW/bU2FMAAAAASUVORK5CYII=";
byte [] sam = abs.getBytes(); // your bytes data goes here.. no need to create string and bytes from it. I did it for demo.
byte [] data = org.apache.commons.codec.binary.Base64.decodeBase64(sam);
FileOutputStream imageOutFile = new FileOutputStream(
"i-love-sample.jpg");
imageOutFile.write(data);
imageOutFile.close();
System.out.println("Image Successfully Manipulated!");
}
输出将是完全相同的图像,但我已将其转换为 jpg
(参见代码),因此图像现在为 jpg。您可以指定任何格式。
输出图像:
看颜色,原样还原无损。
现在,据我了解,您正在从客户端接收 byte
数组,因此请按照上面代码中的注释进行操作。你完成了。甚至不需要使用 javax.imageio.ImageIO
.
希望对您有所帮助...!!
实际图像
生成的图像
我在客户端使用 Javascript(SAP/Open-UI-5) 生成了多个图表(比如最多 14 个),我已将这些图表转换为字节数组,下面是相同
Java脚本代码
var arrCanvas = document.getElementsByTagName("canvas");
var arrImageByte = [];
for(var i=0; i<arrCanvas.length; i++){
var canvas = arrCanvas[i];
if(canvas.width!=0 && (typeof imageNames[i] != 'undefined')){
var imageDetail = {};
var uint8Array = canvas.getContext("2d").getImageData(0,0,canvas.width,canvas.height).data;
imageDetail.byteData = [].slice.call(uint8Array);
imageDetail.name = imageNames[i];
imageDetail.height = canvas.height;
imageDetail.width = canvas.width;
arrImageByte.push(imageDetail);
}
}
现在我使用 REST API 和 AJAX 调用将这些字节发送到服务器端 在下面的服务器端创建图像是我重新创建图像的代码
Java代码
int width = imageDetail.getWidth();
int height = imageDetail.getHeight();
byte[] data = imageDetail.getByteData();
String name = imageDetail.getName();
BufferedImage bufferedImage =new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// calculate array offset
final int o = (x * 3) + (y * width * 3);
// set the pixel color here we will need to convert the byte
// data to an unsigned
// value using &0xFF before passing it to the Color
// constructor
bufferedImage.setRGB(x, y, new Color(data[o + 1] & 0xFF, data[o + 2] & 0xFF, data[o + 3] & 0xFF).getRGB());
}
}
boolean result = ImageIO.write(bufferedImage, "jpg", new File(baseReportFolderLocation+name+".jpg"));
logger.info("Name "+name+" status :: "+result);
但是我的图像颜色与预期的不一样。如何重新创建与在客户端创建时颜色完全相同的图像?
我也试过下面的代码
byte[] data = imageDetail.getByteData();
String name = imageDetail.getName();
BufferedImage bImageFromConvert = ImageIO.read(new ByteArrayInputStream(data));
ImageIO.write(bImageFromConvert, "jpg", new File(baseReportFolderLocation+"New_"+name+".jpg"));
最后一行抛出异常
java.lang.IllegalArgumentException: image == null!
at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925)
at javax.imageio.ImageIO.getWriter(ImageIO.java:1592)
我遵循了您描述的代码(谢谢您,因为它帮助我分析了我面临的问题并且我遵循了类似的方法),在对我所做的 java 代码进行了以下更改之后图像与原始图像完全相同
int width = imageDetail.getWidth();
int height = imageDetail.getHeight();
byte[] data = imageDetail.getByteData();
String name = imageDetail.getName();
BufferedImage bufferedImage =new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int o = (x * 4) + (y * width * 4);
bufferedImage.setRGB(x, y, new Color(data[o] & 0xFF, data[o + 1] & 0xFF, data[o + 2] & 0xFF).getRGB());
}
}
try {
ImageIO.write(bufferedImage, "jpg", new File(PDFReportingUtil.baseReportFolderLocation+name+".jpg"));
} catch (IOException e) {
PDFReportingUtil.logger.error("Error while executing the thread "+Thread.currentThread().getName()+" ",e);
}
这是一个简单的解决方案,避免了循环和所有手动工作。!!
要求: org.apache.commons.codec.binary.Base64
class。所以将其添加到您的 classpath.
如果使用 Maven,请将以下依赖项添加到您的 pom.xml
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
如果使用 jar
作为依赖项,请在您的 lib
或 class 路径中添加以下 jar 文件。
解法:
以下是我的图像,我将使用 byte array
重新创建。
注意颜色:-
- 尺寸:50px * 20px
- 背景 - 白色
- M - 黑色
- A - 黄色
- N - 绿色
- O - 蓝色
- J - 橙色
只是为了验证不同的颜色是否正确保留。
代码
public static void main(String args[]) throws Exception {
String abs = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAUCAIAAABAqPnNAAAAAXNSR0IArs4c6QAAAARnQU1BAACx\n" +
"jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIBSURBVEhL7ZW9SgNREIXzBD5EGt8hjdhZSAqf\n" +
"QVIkkC5gZ5VSWAg2IbUQtrJZSBGDIEQhXVAIN1FCcBtZCwstx/m7u3d/VAQ1Ch4uZGZuYD/OmU1K\n" +
"8Cv1j/UZ/SEs41VKqIpndCAKajQt1QLtv1YPPTjchOOedAVYSpUBUKjvooLzPcI6v5MujxVTuQQW\n" +
"6tuoMsphJVQxAo8qFZrraA73DZhuwBUf0+EhKzwqn+6WJ3530qTitNkK9Qa1HIft+mRrh099caFj\n" +
"m6B/pm0eS6hqNXJHGATK85IJPHeIZtoA01CyiOcAwwmi0KmOBGu3PPJv+WrZvxag/bot+i98YxO8\n" +
"0Q6VwVKqQFmMhTKcYlGC99sO1mWLUI6GT9ypc5dUr8J9cihc8g2MFw7WHRxvwuEB16o0lqWyNAF9\n" +
"2NahmkM00ENRNnTMHNXZSrrbGRkmIYpV7TFfZNpcgqgUVvJ0qUhJp1SG7XGPGfCFJNjsilWw6o7Y\n" +
"OapfTmil4mVKt7kEUS6W83SL5TRcRrxM0Zy+jsonaDcJnvzqGwmKVe8kiHKw0p54uPYB/566c8P2\n" +
"yLJPxbaPE1QsOtdaxEtWlCAqweKnZ3/ZUSnaiN9BOtv6Gn6cIGnZX8Rk7f6jMqGKEkSlV/6nVZwg\n" +
"an1YNz3w2apcgqh1YYlP+N9cYBVqvSG+qV+JBfAKOyszW/bU2FMAAAAASUVORK5CYII=";
byte [] sam = abs.getBytes(); // your bytes data goes here.. no need to create string and bytes from it. I did it for demo.
byte [] data = org.apache.commons.codec.binary.Base64.decodeBase64(sam);
FileOutputStream imageOutFile = new FileOutputStream(
"i-love-sample.jpg");
imageOutFile.write(data);
imageOutFile.close();
System.out.println("Image Successfully Manipulated!");
}
输出将是完全相同的图像,但我已将其转换为 jpg
(参见代码),因此图像现在为 jpg。您可以指定任何格式。
输出图像:
看颜色,原样还原无损。
现在,据我了解,您正在从客户端接收 byte
数组,因此请按照上面代码中的注释进行操作。你完成了。甚至不需要使用 javax.imageio.ImageIO
.
希望对您有所帮助...!!