2009-07-06 55 views
48

Tengo una matriz de enteros que representan una imagen RGB y me gustaría convertirla a una matriz de bytes y guardarla en un archivo.Cómo convertir int [] a byte []

¿Cuál es la mejor forma de convertir una matriz de enteros a la matriz de bytes en Java?

+0

Tal vez va a obtener respuestas mejores y más puntiagudos si uno habla de razones por las que decide convertir int [] a byte []. –

Respuesta

60

Como Brian dice, tiene que encontrar la manera de qué tipo de conversión que necesita.

¿Desea guardarlo como un archivo de imagen "normal" (jpg, png, etc.)?

Si es así, probablemente debería utilizar la API Java Image I/O.

Si desea guardarlo en un formato "en bruto", debe especificarse el orden en que se escriben los bytes y luego usar un IntBuffer y NIO.

Como un ejemplo del uso de una combinación ByteBuffer/IntBuffer:

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]); 
     } 
    } 
} 
3

Primero tiene que decidir cómo convertir 1 entero en un conjunto de bytes.

Probablemente (?) 1 entero a 4 bytes, y utilice los operadores shift (>> o <<) para obtener cada byte (observe ese orden de bytes). Copie en una matriz de bytes 4 veces la longitud de la matriz de enteros.

8

utilizan Tal vez este método

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(); 
} 
+0

esto se dividirá en byte. No creo que esto sea lo que necesita. –

+0

él quiere guardarlo en un archivo para su uso posterior, por lo que sería adecuado – Ram

+0

¿Por qué envuelve 'baos' dentro de' dos'? – Supuhstar

2

si su intención es la de guardar en un archivo que puede que desee guardar directamente en un archivo usando FileOutputStream.write:

OutputStream os = new FileOutputStream("aa"); 
    int[] rgb = { 0xff, 0xff, 0xff }; 
    for (int c : rgb) { 
     os.write(c); 
    } 
    os.close(); 

ya que:

Escribe el byte especificado en esta secuencia de salida. El contrato general para escritura es que un byte se escribe en el flujo de salida. El byte que se escribirá son los ocho bits de bajo orden del argumento b. Los 24 bits de alto orden de b se ignoran.

1

he creado este código y que está funcionando bastante bien:

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; 
    } 
0

me gustaría utilizar 'DataOutputStream' con '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)); 
    } 
} 

Lienzo:

[-1000000, 24000, -1, 40] 
[-1, -16, -67, -64, 0, 0, 93, -64, -1, -1, -1, -1, 0, 0, 0, 40] 
[-1000000, 24000, -1, 40] 
+2

Esto es casi exactamente el mismo que en esta respuesta: https://stackoverflow.com/a/1086071 (la única diferencia que veo es su valor inicial para el 'ByteArrayOutputStream'). ¿Puedes explicar cómo esta respuesta agrega nueva información? – Tom

+0

Simplemente refactorizando. –