Philippe
Philippe

Reputation: 21

Grails - Mongo: storing images as byte array

I'm struggling storing an image as a byte array in Mongo. My domain is quite simple

class Book {
    String title
    String author
    byte[] photo
    String photoType
}

The images are all below 300kB so I would avoid GridFS in the first place. Once persisted, the photo seems to be stored as a String (always of 11 bytes)

db.book.find() { "_id" : NumberLong(15), "author" : "", "photo" : "[B@774dba87", "photoType" : "image/jpeg", "title" : "", "version" : 0 }

My controller reads as follows: def saveImage() {

    def bookInstance
    if(request instanceof MultipartHttpServletRequest) {

        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;
        CommonsMultipartFile file = (CommonsMultipartFile)multiRequest.getFile("photo");

        params.photoType  = file.getContentType()
        print "nb bytes " +file.bytes.length    //TODO

        bookInstance = new Book(params)
        bookInstance.photo=new byte[file.bytes.length]
        bookInstance.photo = file.getBytes()

        def okcontents = ['image/png', 'image/jpeg', 'image/gif']
        if (! okcontents.contains(file.getContentType())) {
            flash.message = "Photo must be one of: ${okcontents}"
            render(view:'create', model:[bookInstance:bookInstance])
            return;
        }

        log.info("File uploaded: " + bookInstance.photoType)
    }


    if (!bookInstance.save()) {
        render(view:'create', model:[bookInstance:bookInstance])
        return;
    }
    flash.message = "Book Photo (${bookInstance.photoType}, ${bookInstance.photo.size()} bytes) uploaded."
    redirect(action: "show", id: bookInstance.id)
}

I am using Grails 2.2 with the mongo plugin...

Thanks in advance for your hints (and happy 2013 btw!)

Cheers Philippe

Upvotes: 2

Views: 3007

Answers (2)

jozh
jozh

Reputation: 2692

encodeBase64 / decodeBase64 is the correct approach for you.

The code you provided works fine in previous mongo-gorm plugin release. In the grails 2.2.0 and 1.1.0.GA mongodb arrays are not converted properly, the bug GPMONGODB-265 submitted for the case.

Consider using alternative gorm plugin or pure groovy mongo wrapper gmongo.

Upvotes: 2

coderLMN
coderLMN

Reputation: 3076

def imgStream = file.getInputStream()
byte[] buf = new byte[310000]
int len =imgStream.read(buf, 0, 310000)
ByteArrayOutputStream bytestream = new ByteArrayOutputStream()
while(len > 0) {
    bytestream.write(buf, 0, len)
    len =imgStream.read(buf, 0, 310000)
}
bookInstance.photo = bytestream.toByteArray()
bookInstance.save()

Upvotes: 0

Related Questions