0

The following code snippet saves an uploaded image in the database:

object MyController extends Controller {

  def upload = Action(multipartFormDataAsBytes) { request =>
    request.body.files foreach {
      case FilePart(key, filename, contentType, bytes) =>
      ...
      // store file in MongoDB GridFS
      ...
    }
    Ok("done")
  }
}

bytes contains the uploaded image to be saved in the database... but before actually saving it I need to:

  1. Determine the size of the image and in case resize it
  2. Determine the type of the image and in case convert it to JPG

Considering that I'll deploy my application to Heruku and I don't know if they installed ImageMagic on their servers, is there any library that let me resize and convert images without having to install native libraries?

I know there is imgscalr – a pure Java 2D library – that provides functionality for resizing images... but I also need to convert them to JPG.

Thanks.

j3d
  • 9,492
  • 22
  • 88
  • 172

4 Answers4

3

Since you're using Scala you can use Scrimage, a Scala image library (basically a wrapper around AWT with a ton of helper functions).

To create an in memory image from an array of bytes (the format does not matter, it will autodetect):

val image = Image(bytes)

To resize this you do:

val resized = image.scaleTo(width, height)

or you can specify the quality / speed:

val resized = image.scaleTo(width, height, ScaleMethod = Bicubic|...others)

Then to write it out as a JPG.

val outBytes = resize.write(Format.JPEG)

To use this library you need to be able to hava a non-headless JRE.

sksamuel
  • 16,154
  • 8
  • 60
  • 108
  • Looks great! I'll try it and compare its performance with the client-side solution we implemented as suggested by Ben Rhouma Zied. Thank you very much for the hint. – j3d Jun 17 '14 at 21:53
1

The library you pointed to works with the classes used by Java's ImageIO image processing library which can save the image as JPEG for you.

As per this answer, you simply do:

val input = new ByteArrayInputStream(bytes)
val image: BufferedImage = ImageIO.read(input)
val resizedImage: BufferedImage = // do imgscalr scaling magic
val outFile = new File("/my/file/location/file.jpg")
ImageIO.write(resizedImage, "jpg", outFile)
Community
  • 1
  • 1
DCKing
  • 4,253
  • 2
  • 28
  • 43
0

Using JAI (Java Advanced Imaging), you can rescale any media format for whose you find codec. We use it with PNG, JPEG, GIF and TIFF.

Best,

cchantep
  • 9,118
  • 3
  • 30
  • 41
0

I'm afraid that this proposal does not meet your need, but I have tried many JVM libraries and after many tries I couldn't get the expected result (loss of quality , big sizes , bad filters ...), also resizing big size images consumes a lot of memory.

So I suggest, that you use Canvas to resize images in the browser using javascript before upload them, and I assure you it's the best solution I have ever found.

size of image to upload > size 4 resized images.

I know it's a difficult task, but In my opinion it worth it, you could even upload your images to mongo directly from the client side.

One last thing if you need to resize a limited number of images and you don't need quality and the size does not bother you then forget what I have said and go for the others solutions.

If you need help with this solution, just notify me.

Cheers,

Ben Rhouma Zied
  • 2,473
  • 3
  • 19
  • 29
  • We already store image streams directly in MongoDB GridFs... We just need to ensure image size and format. Aesthetically speaking, I'd love to let our backend (which consists of a pure REST API written in Scala) do the job... but it is worth to try what you suggest. Do you known where we could find a good example on that? – j3d Jun 16 '14 at 16:48