grails - access image in controller to use in pdf - image

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

Related

Razor pages .Net core displaying a base64 image from Page Model

I am new to .Net Core and Razor pages and have hit a bit of a problem. I am sure this is pretty simple but haven't been able to get the wright answer yet. I have images stored in my database (base64 encoded):
I am in the Code behind IndexModel:
Within this class I have implemented this bound model:
And am attempting to pass the Base64 image string to the Page:
And initially attempted to display the image:
However, everyone would probably already know that this doesn't work. Im guessing the model I am passing is only accessible though certainly htm helper tags and an img src isn't one of them.
Is there a more standard way of getting the result I am after using this model or any other means? I have taken a look at ViewBag but couldn't get this to work either. If anyone is able to offer an example I would be forever grateful!
I have managed to achieve what I want after using ViewData:
[![enter image description here][1]][1]
[![enter image description here][2]][2]
and displayed using:
[![enter image description here][3]][3]
I would still be interested to hear other peoples thoughts on this answer and if there is a better 'best practice' I am missing?
Thanks
[1]: https://i.stack.imgur.com/DgbOm.png
[2]: https://i.stack.imgur.com/0SUVQ.png
[3]: https://i.stack.imgur.com/aUcoX.png
So summary what worked for you:
Controller:
[ViewData]
public string ImageString { get; set; }
public async Task LoadAsync(IdentityUser user)
{
var appUser = await _userManager.Users.Include(x => x.ApplicationUserImage).SingleAsync();
Username = appUser.UserName;
string imageBase64Data = Convert.ToBase64String(appUser.ApplicationUserImage.ImageData);
string imageData = string.Format("data:image/jpg;base64, {0}", imageBase64Data);
this.ImageString = imageData;
}
View:
<div class="form-group">
<img id="UserImage" src="#Model.ImageString" alt="your image" />
</div>

Grails render-plugin does not render images

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.

Dynamically display image (byte array) on jsp with Stripes

I am currently working with Stripes and I have an ActionBean that loads a specific User object JavaBean (Email, First Name, Last Name, Blob image) from my database according to a parameter in the url.
This ActionBean then forward to a JSP page that displays these information by using the ActionBean and accessing the User object instance (property of the ActionBean).
I have no problems displaying the text data (Email, First Name and Last Name) but I don't really know how I can display the Blob image (it's a byte array) dynamically.
Is there a way, maybe using a tag from the Stripes Tag lib to load a event (Resolution) that would load the image from the current ActionBean and display it when the page is loaded?
I thought I could call an Resolution (event) from the User JavaBean as the src of the tag but he doesn't seem to work...
public Resolution loadPicture(){
StreamingResolution sr = null;
return sr = new StreamingResolution("image/jpeg") {
public void stream(HttpServletResponse resp) throws Exception {
OutputStream os = resp.getOutputStream();
os.write(this.user.getBlob());
os.close();
}
};
}
Thanks in advance!
That's not how HTTP and HTML works. A request is used to load the HTML code. This HTML code contains various <img src="..." /> tags, and a new request is made to load each image. You must generate HTML with img tags that have their src point to a Stripes action which will load the image and stream it to the response.
A StreamingResolution is the right approach to implement this action, but the action will have to be called from another request.

how to display images in Grails?

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>

How to load Blobproperty image in Google App Engine?

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.

Resources