I am trying to render the images from /WEB-INF/images/sps in the GSP page using the following code:
def index = {
def baseFolder = grailsAttributes.getApplicationContext().getResource("/").getFile().toString()
println baseFolder
def imagesFolder = baseFolder + '/images/sps'
println imagesFolder
def imageList1 = new File(imagesFolder).list()
println imageList1
def imageList = Arrays.asList(imageList1)
println imageList
imageList
//redirect(action:"displayImages", params:["imageList":imageList])
//render(view:"displayImages")
}
The controller is able to read the images from the fileSystem. But when I try to display them using the following code, the images are not coming.
index.gsp
<g:each in="${imageList}" var="image">
<img src="${resource(dir: 'images', file: image.filename)}" alt="Grails"/>
</g:each>
What mistake am I doing?
EDIT:
When I try with single image, it is working fine - I am able to view the image that is in the WEB-INF/images folder
<img src="${resource(dir: 'images', file: '1.jpg')}" alt="Grails"/>
And there is no HTML code thats getting generated for the loop code(above index.gsp code). Its just blank.
My requirement is to display all the image files that are on the file system folder.
It was simpler. You should return a model from an action as a Map: [imageList: imageList] for imageList to be available by name in GSP.
And yes, can you move images folder to web-app - is it OK that all the world can request your images via HTTP?
you are returning a list of File objects, where you will call the toString method of the file object which most likely returns the absoute file path of the file object.
this would give you something like this in the html source code
<img src="/app/images/c:\path\to\imagefile.png">
try calling
<img src="${resource(dir: 'images', file: image.name)}" alt="Grails"/>
and if that doesnt work, show us the html code that it produces.
In light of new knowledge, the above won't work. The return of File.list() is actually String[] where each string is a file name rather than a complete path.
Anyways, getting a look at the html source would shed light on what exactly gets printed out.
I suspect that maybe g:each doesn't support iterating over simple array types like String[], you could try converting it to a List.
def imageList = Arrays.asList(new File(imagesFolder).list())
Have you tried converting it to a list and using g:each with that?
why are you storing your images in WEB-INF/images? why not just images? i think the code ${resource(dir:'images')} would point to the latter.
You can't render images that are located under WEB-INF using the standard image tag. The images aren't web accessible. You'll need another controller that will stream the images back to the view for you. So something like this:
class AvatarController {
def show = {
def userInstance = User.get(params.id)
def avatarFilePath = new File(userInstance.avatarURL)
response.setContentType("application/png")
response.setContentLength(avatarFilePath.size().toInteger())
OutputStream out = response.getOutputStream();
out.write(avatarFilePath.bytes);
out.close();
}
}
And then to display this image:
<img src="/app/avatar/1234" />
I'll let you work out the conversion of this into your own needs. The key, however, is that you must stream the image back since it isn't web accessible in its current location.
You're better off just serving them outside of WEB-INF, however.
don't store data in WEB-INF, store your images in /web-app/images/
in your controller:
def baseFolder = servletContext.getRealPath("/")
def folder = baseFolder + '/images/' // web-app/images/
def imagesFolder = new File(folder)
def files = imagesFolder.listFiles().toList()
List<String> imageList = []
files.each {
imageList.add(it as String)
}
return imageList
3 in your view:
<g:each in="${imageList}" var="image">
<img src="${resource(dir: 'images', file: image)}" alt="Grails"/>
</g:each>
Related
I have now setup the render-plugin and I get nice PDF-files but I also need to put an image into a few columns in my table. These images are conditionally selected by a data field of the instance.
I have the image in the assets/images folder as I think is the correct place.
I use the following GSP-line in the template that will be used by the renderer to create the PDF.
<td><g:if test="${od?.priceFSC > 0.1}"><asset:image src="checkOut16x16.png" width="16" height="16"/></g:if></td>
As a HTML-view the images prints perfect but when render the PDF they are missing.
I checked the documentation and tried the code from the example:
The controller:
def createPDF() {
def file = new File("asets/CheckOut16x16.png")
def OfferHeader offerHeader = OfferHeader.get(params.id)
[offerHeader: offerHeader])
renderPdf(template: "/stocknote/Stocknote", model: [offerHeader: offerHeader,imageBytes: file.bytes], filename: "Stocknote-"+params.id+".pdf")
}
The view:
<rendering:inlinePng bytes="${imageBytes}" class="some-class" />
I didn't care of the condition here I just wanted to see if it would be printed but it's not because the view crasched:
URI
/stocknote/editStocknote/32
Class
org.grails.taglib.GrailsTagException
Message
Request processing failed; nested exception is org.grails.gsp.GroovyPagesException: Error processing GroovyPageView: [views/stocknote/editStocknote.gsp:32] [views/stocknote/_StocknoteDetail.gsp:3] 'bytes' is required
Caused by
[views/stocknote/editStocknote.gsp:32] [views/stocknote/_StocknoteDetail.gsp:3] 'bytes' is required
I don't know what I've done wrong but error message seems confusing, "Bytes is required" but I have bytes="${imageBytes}".
Hope someone could give me some help or explanation.
Sounds like the path to your file is incorrect, try:
Controller:
def assetResourceLocator
def createPDF() {
def file = assetResourceLocator.findAssetForURI( 'CheckOut16x16.png' )
def OfferHeader offerHeader = OfferHeader.get(params.id)
[offerHeader: offerHeader])
renderPdf(template: "/stocknote/Stocknote", model: [offerHeader: offerHeader,imageBytes: file.getByteArray()], filename: "Stocknote-"+params.id+".pdf")
}
View should be fine as is.
Made a big mistake >_<, The template used to create the PDF is also used by the view from where you order the PDF and at that time the image has not been created by the controller.
So to come through, I had to check the value of the image before rendering.
<g:if test="${imageBytes!= null}"> <rendering:inlinePng bytes="${imageBytes}" /></g:if>
That what was needed.
I'm creating a dynamic pdf with gsp and I'd like to add an image to it but I have no idea how to do this coz simply using <img src="${resource(dir: 'images/vip', file: 'heading.png')}"/> in the gsp does not seem to work. When creating an email you use inline 'pic1', 'image/jpg', resourceLoader.getResource("/images/bawHeader3.png").getFile() in the .sendMail so I was wondering if it's possible to do something similar for pdf. Here's what I got so far:
def downloadBooking() {
def result = Booking.findById(params.id)
renderPdf(template: "/pdf/booking/vipConfirmation", model : result)
}
The above works fine, I just don't know how to add an image into it. Also please show me how I would access the image inside the gsp please.
You need send the bytecode of image to "pdfRenderingService". here is configuration below.
//convert image to bytecode and pass it to the padf rendring service.
def imageBytes=grailsResourceLocator.findResourceForURI('/images/user.png').file.bytes
Passing the value to pdfrendering service.
ByteArrayOutputStream reportBytes = pdfRenderingService.render(template: "/pdf/booking/vipConfirmation", model: [result: result, "imageBytes": imageBytes])
Accessing image in template
<div> <rendering:inlinePng bytes="${imageBytes}" class="header-img"/> </div>
Grails 3.3.9
import org.springframework.core.io.Resource
def assetResourceLocator
Resource resource = assetResourceLocator.findAssetForURI('logo.png')
ByteArrayOutputStream bytes = pdfRenderingService.render(template: "/pdfs/invoice", model: [imageBytes: resource.getInputStream().bytes]) as ByteArrayOutputStream
I'm trying to do a Grails webapp and now I'm trying to display all images in a folder.
To do that I have the following:
def display(){
def dir = new File("/tmp/images")
def list = []
dir.eachFileRecurse() { file ->
def avatarFilePath = new File(file.path)
response.setContentType("application/jpg")
OutputStream out = response.getOutputStream();
out.write(avatarFilePath.bytes);
out.close();
}
}
So using the code above I'm displaying one image using:
<img class="thumbnail" src='${createLink(controller: "images", action: "display")}' />
Using this code, I'm displaying one image.
How do I display all images in that folder?
Do I need to build a list? A list of what? A list of outputstream?
In that case, what should I put in my gsp file?
If the images folder was inside the app structure you could just create links to the image directly. In this case I think you need a controller action that output the contents of one file, and another action that get's the list of the images and request the file content.
class MyController {
private static final File IMAGES_DIR = new File('/tmp/images')
//get the list of files, to create links in the view
def listImages() {
[images: IMAGES_DIR.listFiles()]
}
//get the content of a image
def displayImage() {
File image = new File(IMAGES_DIR.getAbsoluteFilePath() + File.separator + params.img)
if(!image.exists()) {
response.status = 404
} else {
response.setContentType("application/jpg")
OutputStream out = response.getOutputStream();
out.write(avatarFilePath.bytes);
out.close();
}
}
}
And your gsp could do something like
<g:each in="${images}" var="img">
<img class="thumbnail" src='${createLink(controller: "myController", action: "displayImage", params:[img: img.name])}' />
</g:each>
P.S: the code is not tested, may need some adjust.
I'm new to grails (1.3.7) and I've been put in a strange situation with displaying an image from the filesystem. The one.png picture is put into web-app/images/fotos directory. The zz.gsp:
<img src="${resource(dir:'images/fotos', file:'one.png')}" alt="Nothing" />
related to the void action def zz = {} works fine. But if I intend to display the same picture in rawRenderImage.gsp:
<body>
<p>
${fdir} <br/> ${fname} <!-- OK -->
</p>
<g:if test="${fname}">
<img src="${resource(dir:'fdir',file: 'fname')}" alt ="Nothing"/>
</g:if>
</body>
the picture doesn't appear inspite of the parameters fdir and fname pass to the page. The action in the controller is:
def rawRenderImage = {
// def basePath = servletContext.getRealPath("/")
// def basePath = grailsAttributes.getApplicationContext().getResource("/").getFile().toString() + "/images/fotos/"
// def basePath = grailsAttributes.getApplicationContext().getResource("/").getFile().toString()
// def fname = params.photoId + ".png"
// def fname = "/images/fotos/" + params.photoId + ".png"
basePath = "images/fotos" // or basePath=”images” for /images/one.png
fname=”one.png”
[fdir:basePath, fname:fname]
}
Even direct assigns basePath=”images/fotos” and fname=”one.png” don't work, as well as any combinations with basePath to obtain the absolute path. Even the case when I put the picture in images directory doesn't work. I use netbeans, but it also doesn't work in console mode.
Help please.
When passing in your filename and directory as variables in the model, don't quote them in your tag's src attribute. Then the Groovy ${} evaluation will evaluate to the variables and not as Strings.
<g:if test="${fname}">
<img src="${resource(dir:fdir,file:fname)}" alt ="Something"/>
</g:if>
I wrote some codes.
I could save image in BobProperty.
But I cannot load image into HTML page...
source code:
class Product(db.Model):
image = db.BlobProperty()
...
class add:
productImage = self.request.get('image')
product.image = db.Blob(productImage)
product.put()
but i wrote {{product.image}} into html code. But there were like ��袀 ���� ���� ���� (����������� ��(:(������� (������� (��>̢��� (�������>������Y������K��
What should i do if i want load image from datastore?
I use an auxiliary view:
def serve_image(request, image):
if image == "None":
image = ""
response = HttpResponse(image)
response['Content-Type'] = "image/png"
response['Cache-Control'] = "max-age=7200"
return response
and in the model:
def get_image_path(self):
# This returns the url of serve_image, with the argument of image's pk.
# Something like /main/serve_image/1231234dfg22; this url will return a
# response image with the blob
return reverse("main.views.serve_image", args=[str(self.pk)])
and just use {{ model.get_image_path }} instead.
(this is django-nonrel, but I guess you could figure out what it does)
Also, there is a post here about this; you should check it out.