Serving an img src programmatically

45 views
Skip to first unread message

Dan Gravell

unread,
Sep 7, 2015, 11:09:44 AM9/7/15
to Lift
I think I've missed something here. I've always hated having to generate:

<img src="/images/an-image.png"/>

Then have either serve that URL from the static web resources or have a well-known URL pass to a DispatchPF.

Is there a way of doing this inline in code? I think that would be more elegant and potentially more performant at the expense of a bit of memory. I'm thinking of something to associate a function with the generated img src attribute which then returns the bytes for the image.

Dan

Torsten Uhlmann

unread,
Sep 7, 2015, 11:22:19 AM9/7/15
to Lift
Hi Dan,

for most cases I would argue that this is the way the web works and the browser is optimized for, for instance caching the image if it's requested multiple times.

If you need to you can inline an image into the <img> tag, like so:

<img src="data:image/gif;base64,...">

The Image data (note the mime type) is read into memory and base64 encoded and then put into the "src" attribute instead of a url.

Would that help?

Torsten.

--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

---
You received this message because you are subscribed to the Google Groups "Lift" group.
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dan Gravell

unread,
Sep 7, 2015, 11:30:10 AM9/7/15
to Lift
Well in terms of caching I don't mind the function only being called once...? Imagine this being a row from a database, with a field for "thumnail" or something. 

I don't really see how what I'm asking for contravenes the semantics of GET or whatever. I'm just asking to be able to return the bytes in the same place the snippet content was inserted.

If I use a DispatchPF I have to lookup the row again.

I guess I could use base 64, just would rather not...

Dan

Robert Marcano

unread,
Sep 7, 2015, 11:40:56 AM9/7/15
to lif...@googlegroups.com
On 09/07/2015 10:39 AM, Dan Gravell wrote:
> I think I've missed something here. I've always hated having to generate:
>
> <img src="/images/an-image.png"/>

There is SHtml.link() but it returns an <a> element, it doesn't expose
an API to get only the href URL. I have this workaround

def linkSrc(to: String, func: () => Any): String = {
// WORKAROUND generate link URL, get it from an "a" tag because
there is no
// exposed API
SHtml.link(to, func, NodeSeq.Empty).attribute("href").get.text
}

I serve audio using it, for example:

val func = { () =>
val r = fileResponse(f.openStream(), f.length, "audio/ogg;
codecs=opus", None)
throw shortcutResponse(r)
}
<audio src={ SHtml.linkSrc("/download/audio", func) }/>

fileResponse just build a StreamingResponse

>
> Then have either serve that URL from the static web resources or have a
> well-known URL pass to a DispatchPF.
>
> Is there a way of doing this inline in code? I think that would be more
> elegant and potentially more performant at the expense of a bit of
> memory. I'm thinking of something to associate a function with the
> generated img src attribute which then returns the bytes for the image.
>
> Dan
>
> --
> --
> Lift, the simply functional web framework: http://liftweb.net
> Code: http://github.com/lift
> Discussion: http://groups.google.com/group/liftweb
> Stuck? Help us help you:
> https://www.assembla.com/wiki/show/liftweb/Posting_example_code
>
> ---
> You received this message because you are subscribed to the Google
> Groups "Lift" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to liftweb+u...@googlegroups.com
> <mailto:liftweb+u...@googlegroups.com>.

Robert Marcano

unread,
Sep 7, 2015, 11:44:57 AM9/7/15
to lif...@googlegroups.com
The last line isn't SHtml.linkSrc is linkSrc. I have a SHtml subclass
that add more HTML functions, linkSrc could be in any place. I forgot to
remove the "SHtml." from my working core for the example

Dan Gravell

unread,
Sep 8, 2015, 11:12:17 AM9/8/15
to Lift
Thanks. I have followed that and I have the function being executed. But even if I return a StreamingResponse or a Full[StreamingResponse] it always returns a 404...

I have tried preloading into a byte array and returning that, and including the length of the stream, but nothing seems to return an image.

Should the URL be an entry in the site map?

Can it be any URL? Does it "overwrite" an existing URL being used for another page?

Dan

Dan Gravell

unread,
Sep 8, 2015, 11:27:39 AM9/8/15
to Lift
I also tried using fmapFunc and still get a 404...

Dan

Robert Marcano

unread,
Sep 8, 2015, 1:01:36 PM9/8/15
to lif...@googlegroups.com
Did you notice the throw shortcutResponse() call? if not, I missed to
explain it. It is a method
http://liftweb.net/api/26/api/#net.liftweb.http.ResponseShortcutException$
an special control flow exception used by Lift to change the defalt
response of the server side function.

You need to throw that exception shortcutResponse() is only a helper
method that instantiates it

Robert Marcano

unread,
Sep 8, 2015, 1:07:03 PM9/8/15
to lif...@googlegroups.com
On 09/08/2015 10:42 AM, Dan Gravell wrote:
> Thanks. I have followed that and I have the function being executed. But
> even if I return a StreamingResponse or a Full[StreamingResponse] it
> always returns a 404...
>
> I have tried preloading into a byte array and returning that, and
> including the length of the stream, but nothing seems to return an image.
>
> Should the URL be an entry in the site map?
>
> Can it be any URL? Does it "overwrite" an existing URL being used for
> another page?

the URL I think is only useful for access log files. It really doesn't
matter. It appends and query to that URL with the server side function
id. It isn't on my Sitemap

Dan Gravell

unread,
Sep 10, 2015, 5:39:53 AM9/10/15
to Lift
Hooray! That works, thanks. Sorry, my fault, I should've experimented with that line. I guess I didn't expect to be throwing an exception.

SHtml2.linkSrc("", () => {
        val is = optionalThumbnail.get.openStream
        throw ResponseShortcutException.shortcutResponse(StreamingResponse(
     is,
     () => {is.close},
     -1, Nil, Nil, 200)
      )})
Reply all
Reply to author
Forward
0 new messages