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]