Преобразовать ImageOutputStream в byte [] - PullRequest
4 голосов
/ 18 августа 2010

Пытался конвертировать ImageOutputStream в byte [] некоторое время, используя JAI. Любые вклады приветствуются. Спасибо.

Извините, здесь фрагмент кода, над которым я работаю. Я должен был опубликовать это раньше. Проблема, с которой я сталкиваюсь, заключается в том, что я могу получить ByteArrayOutputStream из ImageOutputStream. Но это всегда дает мне ноль байтов. Но если я использую FileOutputStream вместо ByteArrayOuputStream, я могу записать в файл, который имеет ненулевые байты. :

File file = new File("C:/TIFFImages/tiff-image.tiff");
FileInputStream in = new FileInputStream(file);
long filelength = file.length();
byte[] bytes = new byte[(int)filelength]; 
int offset = 0; 
int numRead = 0; 

while (offset < bytes.length && (numRead=in.read(bytes, offset, bytes.length-offset)) >= 0) { 
    offset += numRead; 
} 
if (offset < bytes.length) { 
    throw new IOException("Could not completely read file "+file.getName()); 
} 

ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

RenderedImage src = JAI.create("stream", SeekableStream.wrapInputStream(bais, true));
RenderedOp renderedOp = MedianFilterDescriptor.create(src, MedianFilterDescriptor.MEDIAN_MASK_SQUARE , 1, null);
BufferedImage image = renderedOp.getAsBufferedImage();

ByteArrayOutputStream baos = new ByteArrayOutputStream();

ImageOutputStream  ios =  ImageIO.createImageOutputStream(baos);
//Instead of baos if I pass a FileOutputStream to the above function. It writes non zero
//bytes to the output file

TIFFImageWriterSpi tiffspi = new TIFFImageWriterSpi();
ImageWriter writer = tiffspi.createWriterInstance();
RenderedImage renderedImage = PlanarImage.wrapRenderedImage(src);
writer.setOutput(ios);
writer.write(image);
writer.write(null,new IIOImage(image, null, null), param);

System.out.println("After tiff ImageIO operations" + baos.toByteArray().length);

Спасибо, Вини

Ответы [ 4 ]

3 голосов
/ 29 января 2011

Я почти уверен, что это потому, что вы не вызываете ImageOutputStream.flush() в конце операции - если созданный IOS является MemoryCacheOutputStream, кажется, для некоторых реализаций ImageIO требуется явный сброс.

3 голосов
/ 27 декабря 2010

Создать ImageOutputStream с ByteArrayOutputStream (вместо FileOutputStream)

ByteArrayOutputStream bos = new ByteArrayOutputStream(255);
ImageOutputStream ios = ImageIO.createImageOutputStream(bos);
// use "ios" for image processing

После завершения обработки изображения байты изображения будут доступны в объекте "ios", но смещение будет располагаться в концеобъект "ios"Таким образом, нам нужно поместить смещение в начало объекта «ios», а затем прочитать байты для записи в новый объект ByteArrayOutputStream.Наконец, верните toByteArray () из нового объекта.Как ниже:

        public byte[] getBytes(ImageOutputStream ios) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream(255);
            byte imageByte;
            long counter = 0; 
            try {
                    System.out.println("getStreamPosition()[BEFORE]=" + ios.getStreamPosition());
                    ios.seek(0);
                    System.out.println("getStreamPosition()[AFTER]=" + ios.getStreamPosition());
            } catch (IOException e1) {                       
                    e1.printStackTrace();
            }

            while (true) {
                    try {
                            bos.write(ios.readByte());
                            counter++;
                    } catch (EOFException e) {
                            System.out.println("End of Image Stream");
                            break;
                    } catch (IOException e) {
                            System.out.println("Error processing the Image Stream");
                            break;
                    }
            }
            System.out.println("Total bytes read=" + counter);
            byte[] retValue = bos.toByteArray();
            return retValue;
    }
2 голосов
/ 20 августа 2010

Я получил ответ на этот вопрос, который очень близок к тому, что предложил Гийом. За исключением того, что нет необходимости писать во временный файл между ними. Ниже приведен модифицированный код для преобразования ImageOutputStream в byte []:

ByteArrayOutputStream baos = new ByteArrayOutputStream(37628);
ImageOutputStream  ios =  ImageIO.createImageOutputStream(baos);

//Instead of baos if I pass a FileOutputStream to the above function. It writes non zero
//bytes to the output file

TIFFImageWriterSpi tiffspi = new TIFFImageWriterSpi();
ImageWriter writer = tiffspi.createWriterInstance();
RenderedImage renderedImage = PlanarImage.wrapRenderedImage(src);
writer.setOutput(ios);
writer.write(image);
writer.write(null,new IIOImage(image, null, null), param);

//Create a ByteArrayInputStream to read that ByteArrayOutputStream and read it from ImageIO

ByteArrayInputStream bai = new ByteArrayInputStream(baos.toByteArray());
RenderedImage out = ImageIO.read(bai);
int size = bos.toByteArray().length;

System.out.println(""+ size);

return bos.toByteArray
0 голосов
/ 18 августа 2010

Ну, вы не сможете прочитать из потока output .

Вы должны попытаться получить InputStream от вашего объекта изображения и прочитать оттуда необходимые данные.

Однако, если вы предоставили более подробную информацию о том, чего вы на самом деле пытаетесь достичь, мыможет помочь вам более эффективно.:)

Например, если вы хотите отображать только размер изображений в байтах, есть несколько других способов.

...