4

I am reading two images in a servlet and need to show both at the same time. Currently, only one image is shown (one that is written first). unable to write another image. I do not get any error.

My servlet code goes like this :

    BufferedImage buffImageA = ImageIO.read(getServletContext().getResourceAsStream("/images/3520276097315A.jpg"));
    BufferedImage buffImageB = ImageIO.read(getServletContext().getResourceAsStream("/images/3520276097315B.jpg"));

    logger.logDebug("Images has been read");

    watermark(buffImageA,ApplicationConfig.WATERMARK_TEXT);
    watermark(buffImageB,ApplicationConfig.WATERMARK_TEXT);

    byte[] resultDataA = encodeJPEG(buffImageA, 100);
    byte[] resultDataB = encodeJPEG(buffImageB, 100);

    byte[] combinedImage = new byte[resultDataA.length+resultDataB.length];

    for(int i=0; i<resultDataA.length ;i++){
        combinedImage[i] = resultDataA[i];
    }

    for(int i=resultDataA.length; i<resultDataB.length ;i++){
        combinedImage[i] = resultDataB[i];
    }

    response.setContentType("image/jpeg");

    response.setContentLength(resultDataA.length + resultDataB.length);
    OutputStream os = response.getOutputStream();
    os.write(combinedImage);
    os.close();

//Watermarking process goes here

private void watermark(BufferedImage original, String watermarkText) {

}

private byte[] encodeJPEG(BufferedImage image, int quality) throws IOException {
       ByteArrayOutputStream baos = new ByteArrayOutputStream((int) ((float) image.getWidth() * image.getHeight() / 4));
       JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos);
       JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);
       quality = Math.max(0, Math.min(quality, 100));
       param.setQuality((float) quality / 100.0f, false);
       encoder.setJPEGEncodeParam(param);
       encoder.encode(image);
       byte[] result = baos.toByteArray();
       baos.close();
       return result;
   }

I have tried using ImageIO.write to write the image but failed to get what is desired.

Pankaj Singhal
  • 15,283
  • 9
  • 47
  • 86
usman
  • 1,351
  • 5
  • 23
  • 47

1 Answers1

3

Your second for loop must be like this:

for(int i=resultDataA.length; i<resultDataB.length+resultDataA.length ;i++){
    combinedImage[i] = resultDataB[i-resultDataA.length];
}

EDIT :

This is a compilable, runnable example close to what you're expecting :

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import java.awt.Graphics;

public class Essai2 {

    public static void main(String[] args) {

        try {

            byte[] imageInByte;
            BufferedImage originalImage1 = ImageIO.read(new File("essai1.jpg"));
            BufferedImage originalImage2 = ImageIO.read(new File("essai2.jpg"));

            // convert BufferedImage to byte array
            ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
            ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
            ImageIO.write(originalImage1, "jpg", baos1);
            ImageIO.write(originalImage2, "jpg", baos2);
            baos1.flush();
            baos2.flush();
            byte[] ba1 = baos1.toByteArray();
            byte[] ba2 = baos2.toByteArray();
            imageInByte = new byte[ba1.length + ba2.length];
            //System.out.println(new String(imageInByte));
            System.arraycopy(ba1, 0, imageInByte, 0, ba1.length);
            //System.out.println(new String(imageInByte));
            System.arraycopy(ba2, 0, imageInByte, ba1.length, ba2.length);
            //System.out.println(new String(imageInByte));
            baos1.close();
            baos2.close();

            // convert byte array back to BufferedImage
            InputStream in = new ByteArrayInputStream(imageInByte);

            int w = Math.max(originalImage1.getWidth(), originalImage2.getWidth());
            //int h = Math.max(originalImage1.getHeight(), originalImage2.getHeight());
            int h = originalImage1.getHeight() + originalImage2.getHeight();
            BufferedImage bImageFromConvert = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            //BufferedImage bImageFromConvert = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR );

            //BufferedImage bImageFromConvert = ImageIO.read(in);

            Graphics g = bImageFromConvert.getGraphics();
            g.drawImage(originalImage1, 0, 0, null);
            g.drawImage(originalImage2, 0, originalImage1.getHeight(), null);

            ImageIO.write(bImageFromConvert, "jpg", new File("result.jpg"));

        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

essai1.jpg:

enter image description here

essai2.jpg:

enter image description here

result.jpg:

enter image description here

I haven't found for the moment why there's a third color added to result.jpg. But I think this example can help you and I will fix my code asap.

EDIT2 :

Change :

BufferedImage bImageFromConvert = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

To :

BufferedImage bImageFromConvert = new BufferedImage(w, h, originalImage1.getType());

And it will works fine.

result.jpg:

enter image description here

Michaël
  • 3,679
  • 7
  • 39
  • 64
  • i wondered if i can append two images like above code. i think it is not showing because at the time of byte writing the first image End of file occurrs and it right away terminates the write process and closes the stream ? – usman Mar 26 '13 at 11:18
  • Thanks for the help. But still have question as to Why cannot write from the OutputStream directly. is it ENd of file issue ? – usman Mar 27 '13 at 07:11