Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying image object from controller in the browser

I use playframework 2.2.1 with Java,
I am trying to pass BufferedImage or ByteArray or ByteArrayInputStream
to view template in order to display it in browser directly from memory,
without saving to server storage.
in my view template I request an image:

<img src="@{Application.getImage()}"/>

my Application controller:

public static Result getImage() throws IOException{  
    BufferedImage image = ImageIO.read(new File("public/img/1.jpg"));  
    //some image manipulations  
    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
    ImageIO.write(image, "jpg", baos);  
    return ok(baos.toByteArray()).as("image/jpg");  
}

in generated html I get:

<img src="SimpleResult(200, Map(Content-Type -&gt; image/jpg))">

I've found some info about this topic (one, two, three, four),
but it is usually related to older versions, or Scala versions of play.
Please suggest anything or point to my mistake,
Thanks

like image 271
snp0k Avatar asked Dec 12 '22 09:12

snp0k


2 Answers

For byte array images here's my solution (based on other solutions in stackoverflow):

The Controller:

public static Result getImage(Long id) {
    Entity entity = Entity.find.byId(id);
    ByteArrayInputStream input = null;

    if (entity.getImage() != null) {
        input = new ByteArrayInputStream(entity.getImage());
    } else {
        try {
            byte[] byteArray;
            File file = Play.getFile("/public/images/no_photo.jpg", Play.current());
            byteArray = IOUtils.toByteArray(new FileInputStream(file));
            input = new ByteArrayInputStream(byteArray);
        } catch (Exception e) {

        }
    }

    return ok(input).as("image/jpeg");
}

The routes file:

GET     /entity/image/:id       controllers.Entities.getImage(id:Long)

The view:

<img src=@{routes.Entities.getImage(entity.getId())}>
like image 60
Benchik Avatar answered Jan 31 '23 20:01

Benchik


While it is possible to embed images directly into HTML documents, it's not supported by all browsers. To do it, you need to encode the image as Base64. The resulting image will be 33% larger after encoding than it would have been if you served it normally, and won't be cacheable, so unless the image is very small, you'll get worse performance than serving it up normally. I've used this before for emoticons and other very small graphics. I wouldn't use it for anything larger.

You can read more about the pros and cons here:

Should I embed images as data/base64 in CSS or HTML

To implement this, you need to write a method that returns a String, not a Result, and that String needs to look something like this:

data:image/jpg;base64,<base64 encoded image here>
like image 23
James Roper Avatar answered Jan 31 '23 21:01

James Roper