How to use imgscalr using Grails

3.6k views Asked by At

I've just begun using Groovy and Grails the last few days. I don't have any prior experience of Java, so you'll have to excuse this (probably) very basic question. I've searched Google and Stack Overflow and haven't found anything that helps me with the actually installation.

I have got an image upload working, and I am storing the file on the server. I used a IBM Grails tutorial to guide me through it. That works fine.

I would also like to resize the file in a large, medium, and small format. I wanted to use imgscalr for this, but I cant get it to work. I have downloaded version 4.2 which contains various .jar files. Do I need to put these somewhere on the server and reference them? The only thing I've done is add these lines to buildConfig.groovy

dependencies {
    // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

    // runtime 'mysql:mysql-connector-java:5.1.20'
    compile 'org.imgscalr:imgscalr-lib:4.2'
}

and import org.imgscalr.Scalr.* in my PhotoController.Groovy

Here's my code for saving the file onto the server, I would also like to resize and save the image.

def save() {
    def photoInstance = new Photo(params)

    // Handle uploaded file
    def uploadedFile = request.getFile('photoFile')
    if(!uploadedFile.empty) {
        println "Class: ${uploadedFile.class}"
        println "Name: ${uploadedFile.name}"
        println "OriginalFileName: ${uploadedFile.originalFilename}"
        println "Size: ${uploadedFile.size}"
        println "ContentType: ${uploadedFile.contentType}"

        def webRootDir = servletContext.getRealPath("/")

        def originalPhotoDir = new File(webRootDir, "/images/photographs/original")
        originalPhotoDir.mkdirs()
        uploadedFile.transferTo(new File(originalPhotoDir, uploadedFile.originalFilename))

        BufferedImage largeImg = Scalr.resize(uploadedFile, 1366);
        def largePhotoDir = new File(webRootDir, "/images/photographs/large")
        largePhotoDir.mkdirs()

        photoInstance.photoFile = uploadedFile.originalFilename
    }

    if (!photoInstance.hasErrors() && photoInstance.save()) {
        flash.message = "Photo ${photoInstance.id} created"
        redirect(action:"list")
    }
    else {
        render(view:"create", model:[photoInstance: photoInstance])
    }
}

The error I'm getting is No such property: Scalr for class: garethlewisweb.PhotoController

I'm obviously doing something very wrong. Any guidance appreciated.

3

There are 3 answers

0
Lucas Eduardo On

This is the first google result for "How to use imgscalr in grails" and I was surprised with the lack of informations and examples when googling it. Although the first answer is close, there's still a few mistakes to be corrected.

To anyone that ended here like me through google, heres a more detailed example of how to correctly use this nice plugin:

First, declare the plugin in your BuildConfig.groovy file:

dependencies {
    // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

    // runtime 'mysql:mysql-connector-java:5.1.20'
    compile 'org.imgscalr:imgscalr-lib:4.2'
}

Then, after installed, just paste this piece of code in your controller, in the action that receives the multi-part form with the image uploaded.

def create() {

     def userInstance = new User(params)

     //saving image
     def imgFile = request.getFile('myFile')
     def webRootDir = servletContext.getRealPath("/")
     userInstance.storeImageInFileSystem(imgFile, webRootDir)  

     (...) 
}

Inside my domain, I implemented this storeImageInFileSystem method, that will resize the image and store it in the filesystem. But first, import this to the file:

import org.imgscalr.Scalr
import java.awt.image.BufferedImage
import javax.imageio.ImageIO

And then, implement the method:

def storeImageInFileSystem(imgFile, webRootDir){

    if (!imgFile.empty)
    {
        def defaultPath = "/images/userImages"
        def systemDir = new File(webRootDir, defaultPath)

        if (!systemDir.exists()) {
            systemDir.mkdirs()
        }

        def imgFileDir = new File( systemDir, imgFile.originalFilename)
        imgFile.transferTo( imgFileDir )

        def imageIn = ImageIO.read(imgFileDir);

        BufferedImage scaledImage = Scalr.resize(imageIn, 200);   //200 is the size of the image
        ImageIO.write(scaledImage, "jpg", new File( systemDir, imgFile.originalFilename )); //write image in filesystem

       (...)
    }
}

This worked well for me. Change any details as the need, like the system diretory or the size of the image.

0
tim_yates On

Instead of

import org.imgscalr.Scalr.*

You want

import org.imgscalr.Scalr
import javax.imageio.ImageIO

Then resize needs a BufferedImage (looking at the JavaDocs), so try:

    def originalPhotoDir = new File(webRootDir, "/images/photographs/original")
    originalPhotoDir.mkdirs()
    def originalPhotoFile = new File(originalPhotoDir, uploadedFile.originalFilename)
    uploadedFile.transferTo( originalPhotoFile )

    // Load the image
    BufferedImage originalImage = ImageIO.read( originalPhotoFile )
    // Scale it
    BufferedImage largeImg = Scalr.resize(uploadedFile, 1366);

    // Make the destination folder
    def largePhotoDir = new File(webRootDir, "/images/photographs/large" )
    largePhotoDir.mkdirs()

    // Write the large image out
    ImageIO.write( largeImg, 'png', new File( largePhotoDir, uploadedFile.originalFilename )

Of course, you'll have to watch for files overwriting already existing images

0
AudioBubble On

Put the jar file(s) in the 'lib' directory of your Grails application. You may then delete that line from BuildConfig.groovy