How to dynamically change image at URL (rename github file?)

I’ll have to test but that’s not going to work anyway. You can’t call render in an asynchronous all back like that

Yeah, I was afraid of that...

Use a synchronous call

    def params = [
        uri: "https://raw.githubusercontent.com/lnjustin/wallpaper/master/cropped%20dreamstime_l_155161055.jpg",
        headers: ["Accept": "image/jpeg"]
    ]
    httpGet(params) { resp ->
        if(resp?.data != null) {
            byte[] imageBytes = resp?.data.decodeBase64()
            render contentType: "image/jpeg", data: imageBytes, status: 200
        }
        else {
            log.error "Null Response"
        }
    }

Gives this error:
groovy.lang.MissingMethodException: No signature of method: java.io.ByteArrayInputStream.decodeBase64() is applicable for argument types: () values: [] on line 66 (getImage)

Not sure what to do about that. Does that suggest the image I've got isn't appropriate for decodeBase64? I'm pretty clueless on this file decoding stuff.

The synchronous one just returns a ByteArrayInputStream, not base64. So you just need to convert that stream to bytes. You'd need to google, I don't know the method off hand.

    def params = [
        uri: "https://raw.githubusercontent.com/lnjustin/wallpaper/master/cropped%20dreamstime_l_155161055.jpg",
        headers: ["Accept": "image/jpeg"]
    ]
    httpGet(params) { resp ->
        if(resp?.data != null) {
            byte[] imageBytes = new byte[resp?.data.available()]
            resp?.data.read(imageBytes)
            render contentType: "image/jpeg", data: imageBytes, status: 200
        }
        else {
            log.error "Null Response"
        }
    }

I think this is the way to do it (https://www.baeldung.com/convert-input-stream-to-array-of-bytes)

But I get nothing. No error in the log. No image output. Ugh.

You still can't call render within a closure like that. You need to assign the imageBytes to a variable available outside of the httpGet and then call render on that.

Same result tho. No error, no image output. Any other ideas?

    byte[] imageBytes = null
    def params = [
        uri: "https://raw.githubusercontent.com/lnjustin/wallpaper/master/cropped%20dreamstime_l_155161055.jpg",
        headers: ["Accept": "image/jpeg"]
    ]
    httpGet(params) { resp ->
        if(resp?.data != null) {
            imageBytes = new byte[resp?.data.available()]
            resp?.data.read(imageBytes)
        }
        else {
            log.error "Null Response"
        }
    }
    render contentType: "image/jpeg", data: imageBytes, status: 200

And you're testing using a local endpoint? If so I'll have to test when I'm at a pc

Yup, local endpoint.

The code below works to get the byte data for the image, but does not appear to render the image. Logging shows the right byte count. So must be an issue with rendering those bytes...

    byte[] imageBytes = null
    def params = [
        uri: "https://raw.githubusercontent.com/lnjustin/wallpaper/master/cropped%20dreamstime_l_155161055.jpg",
        headers: ["Accept": "image/jpeg"]
    ]
    httpGet(params) { resp ->
        if(resp?.data != null) {
            imageBytes = resp?.data.getBytes()
            log.debug "bytes size = ${imageBytes.size()}"
        }
        else {
            log.error "Null Response"
        }
    }
    render contentType: "image/jpeg", data: imageBytes, status: 200

I haven't tested it out yet, I was actually going to play with it later today, but this is what @chuck.schwer sent me as an example:

def getImage() {
    String imgBase64 = "iVBORw0..."
    
    render data: imgBase64.decodeBase64(), 
        contentType: "image/png"
} 

So I think what you have should work as long as it's a local endpoint. He told me cloud will NOT work

Hmm. Ok, well let me know if you come up with anything!

Any luck? :slight_smile:

Sorry not yet. I started working on it and got distracted. Just making sure you are on 2.2.1 right?

I wasn’t at first, but it didn’t work after I updated either

I just tested it and it works for me. It does NOT work if it's a cloud endpoint, but does work with:

http://192.168.86.43/apps/api/2921/image?access_token=529020fb-4b3f-4d99-9353-c3881f22e2ac

mappings {
    path("/image") {
        action: [
            GET: "getImage"
        ]
    }

}

def getImage() {
	byte[] imageBytes = null
    def params = [
        uri: "https://raw.githubusercontent.com/lnjustin/wallpaper/master/cropped%20dreamstime_l_155161055.jpg",
        headers: ["Accept": "image/jpeg"]
    ]
    httpGet(params) { resp ->
        if(resp?.data != null) {
            imageBytes = new byte[resp?.data.available()]
            resp?.data.read(imageBytes)
        }
        else {
            log.error "Null Response"
        }
    }
    log.debug imageBytes.size()
    render contentType: "image/jpeg", data: imageBytes, status: 200
}
1 Like

Yup, that worked! Not sure what changed since pretty sure i tried that before. Maybe I hadn't upgraded to 2.2.1 then? Doesn't matter now I suppose, because that worked. Thanks for your help on that!

1 Like

@chuck.schwer have there been any updates lately so we can render an image at a cloud endpoint, not just a local endpoint? Or make the local endpoint secure (https)? I'd like to make the Conditional Image Server app able to serve an image at a cloud endpoint or at least from a secured local endpoint. I'm running into problems due to Chrome now blocking unsecured image content. Thanks