Фактическое изображение

Созданное изображение

У меня есть несколько графиков (скажем, 14 макс.), Которые создаются с использованием Javascript (SAP / Open-UI-5) на стороне клиента. Я преобразовал эти графики в массив байтов. Ниже приведен код для того же
Код JavaScript
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)
@MadMan, потому что массив байтов на стороне клиента несовместим с ImageTO. Запись вызывает ошибку преобразования [B в [I. Вы знаете, как мне получить желаемый результат?
@MadMan У меня такая же проблема. Ребята, вы нашли какое-нибудь решение?
Какое полное название пакета ImageIO ??
@MadMan пакет javax.imageio
niharika и @Hades У меня есть решение .. не могли бы вы, ребята, просто предоставить свой ответ байтового массива .. ?? Или просто скажите мне, массив байтов закодирован по базе 64 или нет ??
@Nope, по крайней мере, в моем случае, поскольку, когда я сделал canvas.getContext ("2d"). GetImageData, он вернул байт uint8array, который копируется в новый массив со знаком из 0-255




Я следил за кодом, который вы описали (спасибо, поскольку он помогает мне анализировать проблему, с которой я столкнулся, и я следовал аналогичному подходу), после внесения следующих изменений в код 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);
}
см. мой ответ, можно ли убрать ненужные петли и ручную работу по воссозданию изображения ... :)
@Hades Это работает отлично ... не знал, что такая небольшая проблема вызывает огромные проблемы, Спасибо.
Вот простое решение, позволяющее избежать петель и всей ручной работы. !!
Необходимые :org.apache.commons.codec.binary.Base64 класс. Так что добавьте это в свой путь к классам.
Если вы используете Maven, добавьте ниже зависимость к вашему pom.xml
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
Если для зависимостей используется jar, добавьте следующий файл jar в свой lib или путь к классам.
Файл Jar-файла кодека Apache Commons
Решение:
Ниже приведено мое изображение, которое я собираюсь воссоздать с помощью byte array.
Обратите внимание на цвет: -
Это просто для того, чтобы убедиться, что разные цвета сохраняются должным образом.
Код
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.
Надеюсь, это помогло ... !!
Спасибо @Mad Man за ответ, но я хочу, чтобы преобразование байтов происходило на стороне клиента, поскольку несколько таких декодированных строк base64 (почти 15) занимают огромное количество времени на преобразование (хотя я реализовал поток в этом преобразовании) подход, который я я использую очень быстро (разница почти в 15-20 секунд) на изображение.
Хотя у меня недостаточно репутации, чтобы проголосовать за ваш ответ, и я могу принять только один в качестве ответа, работающего для меня.
да, я пробовал кодировщик base 64, на преобразование одного изображения ушло почти 40 секунд. Есть ли у декодера apache другой более быстрый способ преобразования строки в байты?
Причина проблемы с производительностью заключается в том, что в соответствии со спецификацией Java, Тип данных char - это один 16-битный символ Unicode. & Тип данных byte - это 8-битовое целое число с дополнением до двух со знаком., поэтому для каждого символа должен быть вызов функции, в противном случае сразу выбросить первые 8 бит char, но затем может произойти потеря данных, поскольку некоторые из символов не работают. t помещается в 8-битное пространство.
Почему вы устанавливаете
bufferedImage.setRGB()вручную, поскольку вы сказали, что изображение уже создано на клиенте, и его байты отправляются в Java-код. ??