I have an array of integers which represent a RGB image and would like to convert it to a byte array and save it to a file.
What\'s the best way to convert an array
As Brian says, you need to work out how what sort of conversion you need.
Do you want to save it as a "normal" image file (jpg, png etc)?
If so, you should probably use the Java Image I/O API.
If you want to save it in a "raw" format, the order in which to write the bytes must be specified, and then use an IntBuffer
and NIO.
As an example of using a ByteBuffer/IntBuffer combination:
import java.nio.*;
import java.net.*;
class Test
{
public static void main(String [] args)
throws Exception // Just for simplicity!
{
int[] data = { 100, 200, 300, 400 };
ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 4);
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(data);
byte[] array = byteBuffer.array();
for (int i=0; i < array.length; i++)
{
System.out.println(i + ": " + array[i]);
}
}
}
I created this code and it's working pretty well:
int IntToByte(byte arrayDst[], int arrayOrg[], int maxOrg){
int i;
int idxDst;
int maxDst;
//
maxDst = maxOrg*4;
//
if (arrayDst==null)
return 0;
if (arrayOrg==null)
return 0;
if (arrayDst.length < maxDst)
return 0;
if (arrayOrg.length < maxOrg)
return 0;
//
idxDst = 0;
for (i=0; i<maxOrg; i++){
// Copia o int, byte a byte.
arrayDst[idxDst] = (byte)(arrayOrg[i]);
idxDst++;
arrayDst[idxDst] = (byte)(arrayOrg[i] >> 8);
idxDst++;
arrayDst[idxDst] = (byte)(arrayOrg[i] >> 16);
idxDst++;
arrayDst[idxDst] = (byte)(arrayOrg[i] >> 24);
idxDst++;
}
//
return idxDst;
}
int ByteToInt(int arrayDst[], byte arrayOrg[], int maxOrg){
int i;
int v;
int idxOrg;
int maxDst;
//
maxDst = maxOrg/4;
//
if (arrayDst==null)
return 0;
if (arrayOrg==null)
return 0;
if (arrayDst.length < maxDst)
return 0;
if (arrayOrg.length < maxOrg)
return 0;
//
idxOrg = 0;
for (i=0; i<maxDst; i++){
arrayDst[i] = 0;
//
v = 0x000000FF & arrayOrg[idxOrg];
arrayDst[i] = arrayDst[i] | v;
idxOrg++;
//
v = 0x000000FF & arrayOrg[idxOrg];
arrayDst[i] = arrayDst[i] | (v << 8);
idxOrg++;
//
v = 0x000000FF & arrayOrg[idxOrg];
arrayDst[i] = arrayDst[i] | (v << 16);
idxOrg++;
//
v = 0x000000FF & arrayOrg[idxOrg];
arrayDst[i] = arrayDst[i] | (v << 24);
idxOrg++;
}
//
return maxDst;
}
I would use 'DataOutputStream' with 'ByteArrayOutputStream'.
public final class Converter {
private static final int BYTES_IN_INT = 4;
private Converter() {}
public static byte [] convert(int [] array) {
if (isEmpty(array)) {
return new byte[0];
}
return writeInts(array);
}
public static int [] convert(byte [] array) {
if (isEmpty(array)) {
return new int[0];
}
return readInts(array);
}
private static byte [] writeInts(int [] array) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream(array.length * 4);
DataOutputStream dos = new DataOutputStream(bos);
for (int i = 0; i < array.length; i++) {
dos.writeInt(array[i]);
}
return bos.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static int [] readInts(byte [] array) {
try {
ByteArrayInputStream bis = new ByteArrayInputStream(array);
DataInputStream dataInputStream = new DataInputStream(bis);
int size = array.length / BYTES_IN_INT;
int[] res = new int[size];
for (int i = 0; i < size; i++) {
res[i] = dataInputStream.readInt();
}
return res;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public class ConverterTest {
@Test
public void convert() {
final int [] array = {-1000000, 24000, -1, 40};
byte [] bytes = Converter.convert(array);
int [] array2 = Converter.convert(bytes);
assertTrue(ArrayUtils.equals(array, array2));
System.out.println(Arrays.toString(array));
System.out.println(Arrays.toString(bytes));
System.out.println(Arrays.toString(array2));
}
}
Prints:
[-1000000, 24000, -1, 40]
[-1, -16, -67, -64, 0, 0, 93, -64, -1, -1, -1, -1, 0, 0, 0, 40]
[-1000000, 24000, -1, 40]
if your intent is to save to file you maybe want to save directly in a file using FileOutputStream.write:
OutputStream os = new FileOutputStream("aa");
int[] rgb = { 0xff, 0xff, 0xff };
for (int c : rgb) {
os.write(c);
}
os.close();
since it:
Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream. The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored.
You need to decide how you convert 1 integer to a set of bytes first.
Most probably (?) 1 integer to 4 bytes, and use the shift (>>
or <<
) operators to get each byte out (watch that byte ordering!). Copy to a byte array 4 times the length of the integer array.
Maybe use this method
byte[] integersToBytes(int[] values)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
for(int i=0; i < values.length; ++i)
{
dos.writeInt(values[i]);
}
return baos.toByteArray();
}