Java - преобразование изображения в Base64
У меня возникла проблема при преобразовании gif-изображения в базовую 64-строку.
Когда я его преобразую, код добавляет мне, как 100 000 AAAAAA, тогда как изображение действительно мало!
Вот мой код:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.util.ArrayList;
public class Main
{
public static void main(String[] args)
{
try
{
FileWriter fstream = new FileWriter("./out.txt");
BufferedWriter out = new BufferedWriter(fstream);
File folder = new File("./flags/");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
Main.readFile(out, listOfFiles[i]);
}
}
out.close();
System.out.println("Done");
}
catch (Exception e) {}
}
public static void readFile(BufferedWriter out, File file)
{
try
{
byte[] byteArray = new byte[102400];
FileInputStream fis = new FileInputStream(file);
String base64String;
int bytesRead = 0;
while ((bytesRead = fis.read(byteArray)) != -1)
{
new String(byteArray, 0, bytesRead);
base64String = Base64.encode(byteArray);
out.write("public static ImageIcon getFlag" + file.getName() + "()");
out.newLine();
out.write("{");
out.newLine();
ArrayList<String> array = Main.cut(base64String);
out.write("return Utils.toImage(\"" + array.get(0) + "\"");
for (int i=1; i<array.size()-1; i++)
{
out.write("<tab>+\"" + array.get(i) + "\"");
}
out.write("<tab>\"" + array.get(array.size() - 1) + "\");");
out.newLine();
out.write("}");
out.newLine();
out.newLine();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static ArrayList<String> cut(String in)
{
ArrayList<String> array = new ArrayList<String>();
while (in.length() > 76)
{
array.add( in.substring(0, 77) );
in = in.substring(77);
}
return array;
}
}
В основном, он записывает в текстовый файл out.txt
кучу java-методов с базовым кодом 64 внутри.
Вот небольшая часть вывода:
return Utils.toImage("R0lGODlhEAALANUAANPTAPZva/n5AfLySPz8iYqY3O01NgoksbGZa+kYGOskJKi05vb2XZ+r4+05O"<tab>+"Pv7eO3tKPv7bZak4dSvebC76tC2iPNISPX1UMkAAMm6U/NWTeYAAF5y1LqlevNaWpSh3e7uQ+1CQt"<tab>+"gAAKOv5Vds1C1IvpGf37a/7OnTYZ6q6NGkamd71/LyPusvLvFiTEFbx9rPb/HuaczATd7eAPAAAH2"<tab>+"N2vE+PMqiYuXQUsKufJqn4jlRxUlhy+CpelFnz/PxbyH5BAAAAAAALAAAAAAQAAsAAAaQwBVnSBIY"<tab>+"jzTaZsk5OSmEKOHxCAQ8nk1zMUo9Ir8Y42Kx2Dyi5qihi1QqkxzZZtCISBS2JNILoFQDdC0WIj4UO"<tab>+"hImDBMoLjcsBi0KISI8C4kFMB0uOAgykgkOGC8LJgUFFx0IqxAKCQkGGDsjpzUDLBkZEBCvCS0YJW"<tab>+"wfBQxjAyAgDpG/OwfOBzPRANMY1dVBADsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<tab>
Спасибо.
Изменить: я использую код base64 из этого вопроса: qaru.site/info/17388/...
Ответы
Ответ 1
byte[] byteArray = new byte[102400];
base64String = Base64.encode(byteArray);
Этот код будет кодировать 102400 байт, независимо от того, сколько данных вы фактически используете в массиве.
while ((bytesRead = fis.read(byteArray)) != -1)
Вам нужно использовать значение bytesRead где-то.
Кроме того, это может не прочитать весь файл в массиве за один раз (он читает столько же, сколько и в буфере ввода-вывода), поэтому ваш цикл, вероятно, не сработает, вы можете получить половину изображения в вашем массиве.
Я бы использовал Apache Commons IOUtils здесь:
Base64.encode(FileUtils.readFileToByteArray(file));
Ответ 2
Во-первых, эта строка кода:
while ((bytesRead = fis.read(byteArray)) != -1)
эквивалентно
while ((bytesRead = fis.read(byteArray, 0, byteArray.length)) != -1)
Итак, он записывает в byteArray из смещения 0, а не из того, где вы написали ранее.
Вам нужно что-то вроде этого:
int offset = 0;
int bytesRead = 0;
while ((bytesRead = fis.read(byteArray, offset, byteArray.length - offset) != -1) {
offset += bytesRead;
}
После того, как вы прочитали данные (байты), вы можете преобразовать их в Base64.
Однако есть большие проблемы - вы используете массив фиксированного размера, поэтому слишком большие файлы не будут правильно преобразовываться, и из-за этого код тоже запутан.
Я бы расколол массив байтов и пошел с чем-то вроде этого:
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
// commons-io IOUtils
IOUtils.copy(fis, buffer);
byte [] data = buffer.toByteArray();
Base64.encode(data);
Или конденсируйте его дальше, как Thilo с FileUtils.
Ответ 3
Линия
base64String = Base64.encode(byteArray);
преобразует полный массив (102400 байт) в Base64, а не только количество прочитанных байтов. Вам нужно передать ему количество байтов.
Ответ 4
new String(byteArray, 0, bytesRead);
не изменяет массив. Вы должны использовать System.arrayCopy
, чтобы обрезать массив до фактического размера данных. В противном случае вы обрабатываете все 102400 байтов, большинство из которых являются нулями.
Ответ 5
Late GraveDig... Просто ограничьте массив байтов размером файла.
FileInputStream fis = new FileInputStream( file );
byte[] byteArray= new byte[(int) file.length()];
Ответ 6
Вы можете использовать файл Object для получения длины файла для инициализации массива:
int length = Long.valueOf(file.length()).intValue();
byte[] byteArray = new byte[length];
Ответ 7
Вы можете создать большой массив, а затем скопировать его в новый массив, используя System.arrayCopy
int contentLength = 100000000;
byte[] byteArray = new byte[contentLength];
BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());
while ((bytesRead = inputStream.read()) != -1)
{
byteArray[count++] = (byte)bytesRead;
}
byte[] destArray = new byte[count];
System.arraycopy(byteArray, 0, destArray , 0, count);
destArray будет содержать требуемую информацию
Ответ 8
Я понимаю, что это старый вопрос, но, возможно, кто-то найдет мой пример кода полезным. Этот код кодирует файл в Base64, затем декодирует его и сохраняет его в новом месте.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import org.apache.commons.codec.binary.Base64;
public class Base64Example {
public static void main(String[] args) {
Base64Example tempObject = new Base64Example();
// convert file to regular byte array
byte[] codedFile = tempObject.convertFileToByteArray("your_input_file_path");
// encoded file in Base64
byte[] encodedFile = Base64.encodeBase64(codedFile);
// print out the byte array
System.out.println(Arrays.toString(encodedFile));
// print the encoded String
System.out.println(encodedFile);
// decode file back to regular byte array
byte[] decodedByteArray = Base64.decodeBase64(encodedFile);
// save decoded byte array to a file
boolean success = tempObject.saveFileFromByteArray("your_output_file_path", decodedByteArray);
// print out success
System.out.println("success : " + success);
}
public byte[] convertFileToByteArray(String filePath) {
Path path = Paths.get(filePath);
byte[] codedFile = null;
try {
codedFile = Files.readAllBytes(path);
} catch (IOException e) {
e.printStackTrace();
}
return codedFile;
}
public boolean saveFileFromByteArray(String filePath, byte[] decodedByteArray) {
boolean success = false;
Path path = Paths.get(filePath);
try {
Files.write(path, decodedByteArray);
success = true;
} catch (Exception e) {
e.printStackTrace();
}
return success;
}
}