I am using the approach suggested by Howard below in conjunction with the UploadedFile component and JAI to upload an image and re-scale it before saving it into the database. My code is provided below
This may not be very relevant to many T5 users but I thought of sharing my code anyway. Petros ############################# UserDetails.html <imgimg src="${userImageURL}" width="${imageWidth}" height="${imageHeight}" border="0"/> <inputinput t:type="upload" t:id="file"/> ############################# UserDetails.java @Persist protected UploadedFile uploadedFileCmpnt; @Inject private ComponentResources cmpntResources; private InputStream imageFileInputStream = null; public void pageDetached() { try { imageFileInputStream.close(); if(uploadedFileCmpnt != null) { uploadedFileCmpnt.getStream().close(); } } catch (IOException e) { // TODO Log an error e.printStackTrace(); } } public Object onImage(long productId) throws IOException { imageFileInputStream = new ByteArrayInputStream( getUser().getUserProfileImages().getImageFileAsBytesScaledThumb()); return createStreamResponse(imageFileInputStream); } private StreamResponse createStreamResponse(final InputStream is) { return new StreamResponse() { public String getContentType() { return "img/jpeg"; } public InputStream getStream() throws IOException { return is; } }; } public Link getUserImageURL() throws IOException { return cmpntResources.createActionLink("image", false, 0); } Object onSuccessFromFormUserDetails() { if(uploadedFileCmpnt != null) { getAndScaleUserImage(uploadedFileCmpnt); } userManager.saveUser(getUser()); } protected void getAndScaleUserImage(UploadedFile uploadedFileCmpnt) throws IOException { byte[] imageAsByteArrayNotScaled = StreamUtils.getBytesArrayFromInputStream(uploadedFileCmpnt.getStream()); byte[] imageAsByteArrayCompressedMain = ImageUtils.getScaledImageByteArray(500, 0, imageAsByteArrayNotScaled); byte[] imageAsByteArrayCompressedThumb = ImageUtils.getScaledImageByteArray(200, 0, imageAsByteArrayNotScaled); getUser().setImageFileAsBytesScaledThumb(imageAsByteArrayCompressedThumb); getUser().setImageFileAsBytesScaledMain(imageAsByteArrayCompressedMain); getUser().setImageFileName(uploadedFileCmpnt.getFileName()); } ############################################################## ImageUtils.java public static byte[] getScaledImageByteArray(int newWidthInPixels, int newHeightInPixels, byte[] unscaledImageAsByteArray) throws IOException { InputStream unscaledImageInputStream = new ByteArrayInputStream(unscaledImageAsByteArray); SeekableStream seakableStream = ByteArraySeekableStream.wrapInputStream(unscaledImageInputStream, true); RenderedOp objImage = JAI.create("stream", seakableStream); float xScale = (float)newWidthInPixels / objImage.getWidth(); float yScale = (float)newHeightInPixels / objImage.getHeight(); if(xScale == 0){xScale = yScale;} if(yScale == 0){yScale = xScale;} ParameterBlock pb = new ParameterBlock(); pb.addSource(objImage); // The source image pb.add(xScale); // The xScale pb.add(yScale); // The yScale pb.add(0.0F); // The x translation pb.add(0.0F); // The y translation pb.add(new InterpolationNearest()); // The interpolation objImage = JAI.create("scale", pb, null); BufferedImage bufferedScaledImage = objImage.getAsBufferedImage(); ByteArrayOutputStream scaledImageAsByteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(bufferedScaledImage, "jpeg", scaledImageAsByteArrayOutputStream); byte[] scaledImageAsByteArray = scaledImageAsByteArrayOutputStream.toByteArray(); scaledImageAsByteArrayOutputStream.close(); unscaledImageInputStream.close(); return scaledImageAsByteArray; } ################################################################### Howard Lewis Ship wrote: > > ---------- Forwarded message ---------- > From: Howard Lewis Ship <[EMAIL PROTECTED]> > Date: Jun 7, 2007 10:10 PM > Subject: Re: How to load a image dynamically in tapestry5.0.4 > To: "[EMAIL PROTECTED]" <[EMAIL PROTECTED]> > > > Let me use 5.0.5 syntax since its a little cleared and will be totally > relevant pretty soon. > > Let's say you have a page named Catalog on which you want to display > images: > > Catalog.html: > > <t:loop source="products" value="product"> > ${productImageURL} > </t:loop> > > Ok, now Catalog.java (i'll omit the ordinary getters/setters): > > public class Catalog { > private Product _product; > > @Inject > private ComponentResources _resources; > > public Link getProductImageURL() { > return _resources.createActionLink("image", false, _product.getId()); > } > > public Object onImage(long productId) { > > final InputStream is = // ... get InputStream from productId > > return new StreamResponse() { > > public String getContentType() { return "img/jpeg"; } > > public InputStream getStream() throws IOException { return is; } > }; > > } > > ... so what do we have? > > We have an element that gets its URL from the code. > > getProductImageURL() generates a URL that triggers inside the Catalog > page (not a component within the page), with an event type of "image" > and places the product's id property as path info. It will look like: > > http://localhost:8080/catalog:image/12345 > > Now, when the page renders, the element in the browser will use > that URL. Thus a new request comes up, which fires the "image" event > on the Catalog page. We provide an event hander as "onImage" > (whereas normally we use "onAction"). > > The return value is an instance of StreamResponse (that's an > interface). In the current code, a StreamResponse provides a content > type and an InputStream. > > Tapestry will use this to "pump down" the bytes in the stream. > > The only thing new in 5.0.5 is the way we were able to put an > expansion into the src attribute of the element. In 5.0.4 you'd > have to use a Img component. > > That's it ... I like this because it was hard to do (properly) in T4 > and is cake in T5. > > > > On 6/7/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: >> Hi Howard, >> >> In your reply below you mentioned that >> > There's another approach used when the data is inside the database, but >> we >> > can dive into that if the above solution is insufficient. >> >> Can you please provide some more information as to what this approach is? >> Knowing how busy you are I don't expect a complete solution but I would >> appreciate it if you could point me to the right direction. >> >> I am thinking of an approach similar to JSP where you write the byte[] >> retrieved from the database directly into the OutputStream but I don't >> know if this is the best way to do this with T5 or if it's even possible. >> >> Thanks >> Petros >> >> >> Howard Lewis Ship wrote: >> > >> > In order to answer this question, some background is needed. >> > >> > If you know the product's id (whatever you use, where it's SKU number >> or >> > a >> > surrogate key) ... what is the exact process from going from that to a >> URL >> > suitable for an tag? >> > >> > That is ... are the images stored in the database? Or are they on the >> > file >> > system somewhere? If they are files on the file system, are those >> files >> > mapped to a client-visible URL? >> > >> > In the latter case, you can do something like: >> > >> > prop:productImageURL >> > >> > public String getProductImageURL() { >> > return "http://static.myco.com/product-images/" + _productId + >> ".gif"; >> > } >> > >> > >> > >> > Assigning a t:id to a tag without specifying a component type creates >> an >> > Any >> > component, a component that just renders whatever tag and informal >> > parameters you provide it. Here wer'e linking that to some Java code >> in >> > the >> > corresponding page or component that computes the URL of the product >> based >> > on an instance variable. Probably your example is more complicated, >> but >> > you >> > get the idea. >> > >> > There's another approach used when the data is inside the database, but >> we >> > can dive into that if the above solution is insufficient. >> > >> > Assets are useful for accessing resources inside the web application >> > context, or on the classpath, and includes logic related to >> localization >> > ... >> > but it is not always appropriate when accessing resources that are well >> > outside the web application itself. >> > >> > On 5/19/07, Allen Guo <[EMAIL PROTECTED]> wrote: >> >> >> >> Hi All, >> >> >> >> I want to show the ProductDetail page with product image. It looks >> like >> >> p_001.jpg . >> >> You know, every product has different image name,so I need to pass the >> >> string 'p_001.jpg' to the corresponding page. >> >> As result the img tag should look like ${product.image} or >> >> I can use Asset to do it. >> >> >> >> But I tried to do it using the first approach, exception occured. >> >> And I don't know how to the second approach. >> >> Can anyone give me an idea? >> >> >> >> Thank in advance >> >> Allen Guo >> >> >> >> >> >> --------------------------------------------------------------------- >> >> To unsubscribe, e-mail: [EMAIL PROTECTED] >> >> For additional commands, e-mail: [EMAIL PROTECTED] >> >> >> >> >> > >> > >> > -- >> > Howard M. Lewis Ship >> > TWD Consulting, Inc. >> > Independent J2EE / Open-Source Java Consultant >> > Creator and PMC Chair, Apache Tapestry >> > Creator, Apache HiveMind >> > >> > Professional Tapestry training, mentoring, support >> > and project work. http://howardlewisship.com >> > >> > >> Quoted from: >> http://www.nabble.com/How-to-load-a-image-dynamiclly-in-tapestry5.0.4-tf3784430.html#a10707188 >> >> > > > -- > Howard M. Lewis Ship > TWD Consulting, Inc. > Independent J2EE / Open-Source Java Consultant > Creator and PMC Chair, Apache Tapestry > Creator, Apache HiveMind > > Professional Tapestry training, mentoring, support > and project work. http://howardlewisship.com > > > -- > Howard M. Lewis Ship > TWD Consulting, Inc. > Independent J2EE / Open-Source Java Consultant > Creator and PMC Chair, Apache Tapestry > Creator, Apache HiveMind > > Professional Tapestry training, mentoring, support > and project work. http://howardlewisship.com > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > > -- View this message in context: http://www.nabble.com/Fwd%3A-How-to-load-a-image-dynamically-in-tapestry5.0.4-tf3890149.html#a11057566 Sent from the Tapestry - User mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]