Skip to main content

[JAI] Image cropping to fixed width and height

7 replies [Last post]
Anonymous

Hi,

I want to use JAI to resize and crop JPEG/GIF images. I need the final
images to share the same width and height.
So, I think, firstly I should resize the original image (of any size)
- keeping the proportions intact. And after this first step
I want to end up having an image with the best possible 'match' to the
width and height I want for my final image (as close as possible).
Secondly, I want to crop the image and end up with the final image -
having the width and height I intended for it.
I also would like to have an option for where the cropping should
ocurr. Left upper corner, right upper corner or in the centre.

Is this possible? I'd very grateful for help with this.

/best regards, Håkan Jacobsson - Java developer in Stockholm, Sweden

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Thad Humphries

Completely possible and not difficult. I'm using this technique in a
servlet to scale and crop images from a repository for display in a web
browser.

On Mon, Jan 4, 2010 at 10:57 AM, Håkan Jacobsson <
hakan.jacobsson@aftonbladet.se> wrote:

> Hi,
>
> I want to use JAI to resize and crop JPEG/GIF images. I need the final
> images to share the same width and height.
> So, I think, firstly I should resize the original image (of any size) -
> keeping the proportions intact. And after this first step
> I want to end up having an image with the best possible 'match' to the
> width and height I want for my final image (as close as possible).
> Secondly, I want to crop the image and end up with the final image - having
> the width and height I intended for it.
> I also would like to have an option for where the cropping should ocurr.
> Left upper corner, right upper corner or in the centre.
>
> Is this possible? I'd very grateful for help with this.
>
> /best regards, Håkan Jacobsson - Java developer in Stockholm, Sweden
>

--
"Thou art violently carried away from grace: there is a devil haunts thee in
the likeness of an old fat man." --William Shakespeare, 'Henry IV, Pt 1',
II, iv
[att1.html]

Håkan Jacobsson

Thad and Mike,

Many thanx for damn fast responses.=)

Thad, how do you treat images that are to small originally?

And dare I ask you for some sample code?

/Håkan - enjoying this mailing list from the very start;)

4 jan 2010 kl. 17.05 skrev Thad Humphries:

> Completely possible and not difficult. I'm using this technique in
> a servlet to scale and crop images from a repository for display in
> a web browser.
>
> On Mon, Jan 4, 2010 at 10:57 AM, Håkan Jacobsson > > wrote:
> Hi,
>
> I want to use JAI to resize and crop JPEG/GIF images. I need the
> final images to share the same width and height.
> So, I think, firstly I should resize the original image (of any
> size) - keeping the proportions intact. And after this first step
> I want to end up having an image with the best possible 'match' to
> the width and height I want for my final image (as close as possible).
> Secondly, I want to crop the image and end up with the final image -
> having the width and height I intended for it.
> I also would like to have an option for where the cropping should
> ocurr. Left upper corner, right upper corner or in the centre.
>
> Is this possible? I'd very grateful for help with this.
>
> /best regards, Håkan Jacobsson - Java developer in Stockholm, Sweden
>
> --
> "Thou art violently carried away from grace: there is a devil haunts
> thee in the likeness of an old fat man." --William Shakespeare,
> 'Henry IV, Pt 1', II, iv
>

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Thad Humphries

On the browser side, I instantiate the display area in the browser, then
send it's dimensions to the servlet, along with an identifying ID of the
image, and any information on scaling and rotation. (I've also found that I
need to send a random number or timestamp, thus making a unique URL so I can
be certain there will be no caching. I've found you can't rely on no-cache,
etc.)

My code is pretty big to cover the wide array of images I handle--TIFFs of
all sorts, JPEG, PNG, special cases, etc.--but the manipulation is all right
out of the JAI document. For example,

private PlanarImage getRotatedImage(PlanarImage pi, TransposeType type)
{
if ( type == null )
return pi;
ParameterBlock pb = new ParameterBlock();
pb.addSource(pi);
pb.add(type);
return JAI.create("transpose", pb);
}

When scaling, I check the image depth, as 1-bit images scale better using
SubsampleBinaryToGray:

private PlanarImage getScaledImage(PlanarImage pi, float scale) {
ParameterBlock pb = new ParameterBlock();
pb.addSource(pi);
pb.add(scale); // x scale factor
pb.add(scale); // y scale factor
pb.add(0.0F); // x translate
pb.add(0.0F); // y translate

PlanarImage scaledImage = null;
int pixelSize = pi.getColorModel().getPixelSize();
if (pixelSize == 1 && scale <= 1.0F) {
RenderingHints hints = getGrayRenderingHints();
scaledImage = JAI.create("SubsampleBinaryToGray", pb, hints);
}
else {
pb.add(null);
scaledImage = JAI.create( "Scale", pb );
}
return scaledImage;
}

I test the X and Y axis of the image vs the display area, and select
whichever fits the image into the display area for complete viewing. From
there the use can scale, rotate, etc. Since the image is in a browser, each
change in the image is call back to the server, where I keep some
information in the servlet session.

Images that would fit into the display area without scaling I return at
their size, and let the rest of the display area stay white.

For reading the image you can use JAI.create() since that gives you the
PlanarImage, or you can use ImageIO.read() to get the BufferedImage, then
PlanarImage.wrapRenderedImage(bufImg) to get the Planarimage. For writing
back the image I use ImageIO.write().

private void exportToBrowser(HttpServletResponse response, PlanarImage
image)
throws IOException {
response.setContentType("image/png");
response.setHeader("cache-control",
"no-cache,no-store,must-revalidate");
ImageIO.write(image, "png", response.getOutputStream());
response.flushBuffer();
}

On Mon, Jan 4, 2010 at 11:16 AM, Håkan Jacobsson <
hakan.jacobsson@aftonbladet.se> wrote:

> Thad and Mike,
>
> Many thanx for damn fast responses.=)
>
> Thad, how do you treat images that are to small originally?
>
> And dare I ask you for some sample code?
>
> /Håkan - enjoying this mailing list from the very start;)
>
> 4 jan 2010 kl. 17.05 skrev Thad Humphries:
>
>
> Completely possible and not difficult. I'm using this technique in a
>> servlet to scale and crop images from a repository for display in a web
>> browser.
>>
>> On Mon, Jan 4, 2010 at 10:57 AM, Håkan Jacobsson <
>> hakan.jacobsson@aftonbladet.se> wrote:
>> Hi,
>>
>> I want to use JAI to resize and crop JPEG/GIF images. I need the final
>> images to share the same width and height.
>> So, I think, firstly I should resize the original image (of any size) -
>> keeping the proportions intact. And after this first step
>> I want to end up having an image with the best possible 'match' to the
>> width and height I want for my final image (as close as possible).
>> Secondly, I want to crop the image and end up with the final image -
>> having the width and height I intended for it.
>> I also would like to have an option for where the cropping should ocurr.
>> Left upper corner, right upper corner or in the centre.
>>
>> Is this possible? I'd very grateful for help with this.
>>
>> /best regards, Håkan Jacobsson - Java developer in Stockholm, Sweden
>>
>
--
"Thou art violently carried away from grace: there is a devil haunts thee in
the likeness of an old fat man." --William Shakespeare, 'Henry IV, Pt 1',
II, iv
[att1.html]

Håkan Jacobsson

Ah, I see, you let the user select the area of the final image? What I
want to do is to make the scaling and cropping automatically.
A little bit more complicated, I think.

I guess the tricky part is to decide how to scale the image. Before
cropping. Like I said, the original images may come in any size.
Does someone have a recommendation here? Should I try to find the
smallest size possible (regarding both height and width) and then crop?
Some images won't be recognizable after this, I guess. Escpecially If
the original image is a lot wider than high or vice versa.

/best regards, Håkan

4 jan 2010 kl. 18.44 skrev Thad Humphries:

> On the browser side, I instantiate the display area in the browser,
> then send it's dimensions to the servlet, along with an identifying
> ID of the image, and any information on scaling and rotation. (I've
> also found that I need to send a random number or timestamp, thus
> making a unique URL so I can be certain there will be no caching.
> I've found you can't rely on no-cache, etc.)
>
> My code is pretty big to cover the wide array of images I handle--
> TIFFs of all sorts, JPEG, PNG, special cases, etc.--but the
> manipulation is all right out of the JAI document. For example,
>
> private PlanarImage getRotatedImage(PlanarImage pi,
> TransposeType type) {
> if ( type == null )
> return pi;
> ParameterBlock pb = new ParameterBlock();
> pb.addSource(pi);
> pb.add(type);
> return JAI.create("transpose", pb);
> }
>
> When scaling, I check the image depth, as 1-bit images scale better
> using SubsampleBinaryToGray:
>
> private PlanarImage getScaledImage(PlanarImage pi, float scale) {
> ParameterBlock pb = new ParameterBlock();
> pb.addSource(pi);
> pb.add(scale); // x scale factor
> pb.add(scale); // y scale factor
> pb.add(0.0F); // x translate
> pb.add(0.0F); // y translate
>
> PlanarImage scaledImage = null;
> int pixelSize = pi.getColorModel().getPixelSize();
> if (pixelSize == 1 && scale <= 1.0F) {
> RenderingHints hints = getGrayRenderingHints();
> scaledImage = JAI.create("SubsampleBinaryToGray", pb,
> hints);
> }
> else {
> pb.add(null);
> scaledImage = JAI.create( "Scale", pb );
> }
> return scaledImage;
> }
>
> I test the X and Y axis of the image vs the display area, and select
> whichever fits the image into the display area for complete
> viewing. From there the use can scale, rotate, etc. Since the
> image is in a browser, each change in the image is call back to the
> server, where I keep some information in the servlet session.
>
> Images that would fit into the display area without scaling I return
> at their size, and let the rest of the display area stay white.
>
> For reading the image you can use JAI.create() since that gives you
> the PlanarImage, or you can use ImageIO.read() to get the
> BufferedImage, then PlanarImage.wrapRenderedImage(bufImg) to get the
> Planarimage. For writing back the image I use ImageIO.write().
>
> private void exportToBrowser(HttpServletResponse response,
> PlanarImage image)
> throws IOException {
> response.setContentType("image/png");
> response.setHeader("cache-control", "no-cache,no-store,must-
> revalidate");
> ImageIO.write(image, "png", response.getOutputStream());
> response.flushBuffer();
> }
>
> On Mon, Jan 4, 2010 at 11:16 AM, Håkan Jacobsson > > wrote:
> Thad and Mike,
>
> Many thanx for damn fast responses.=)
>
> Thad, how do you treat images that are to small originally?
>
> And dare I ask you for some sample code?
>
> /Håkan - enjoying this mailing list from the very start;)
>
> 4 jan 2010 kl. 17.05 skrev Thad Humphries:
>
>
> Completely possible and not difficult. I'm using this technique in
> a servlet to scale and crop images from a repository for display in
> a web browser.
>
> On Mon, Jan 4, 2010 at 10:57 AM, Håkan Jacobsson > > wrote:
> Hi,
>
> I want to use JAI to resize and crop JPEG/GIF images. I need the
> final images to share the same width and height.
> So, I think, firstly I should resize the original image (of any
> size) - keeping the proportions intact. And after this first step
> I want to end up having an image with the best possible 'match' to
> the width and height I want for my final image (as close as possible).
> Secondly, I want to crop the image and end up with the final image -
> having the width and height I intended for it.
> I also would like to have an option for where the cropping should
> ocurr. Left upper corner, right upper corner or in the centre.
>
> Is this possible? I'd very grateful for help with this.
>
> /best regards, Håkan Jacobsson - Java developer in Stockholm, Sweden
>
> --
> "Thou art violently carried away from grace: there is a devil haunts
> thee in the likeness of an old fat man." --William Shakespeare,
> 'Henry IV, Pt 1', II, iv
>

/Med vänliga hälsningar,

Håkan Jacobsson - Systemutvecklare på Aftonbladets mobilsajt
tel: 0703-82 69 76
mail: hakan.jacobsson@aftonbladet.se

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Anonymous

Sorry, but I had to delete my message

Message was edited by: helaha

Message was edited by: helaha

Nidel, Mike

You can definitely do this with JAI.

A lot of the calculations you will do on your own, for example
computing the scale factor and the crop region. JAI includes a
scale operator and a crop operator that will do what you want.

Are you planning to save the JPEG or GIF images back to a JPEG
or GIF? I would recommend using ImageIO to read and write the
images, using the JAI operations in between. Here is some
pseudocode to get you started:

RenderedImage startImage = loadUsingImageIO(filename);
// determine scale factor using width & height of original
float scaleFactor = computeScaleFactor(startImage);
RenderedImage scaledImage = doScale(startImage, scaleFactor);
RenderedImage croppedImage = doCrop(scaledImage);
writeUsingImageIO(croppedImage);

Obviously you will need to write each of these methods yourself.
Only the doScale and doCrop will require JAI code.

I hope this will get you started off OK. If you have questions
about how to implement the details feel free to ask.

cheers,
Mike

> -----Original Message-----
> From: Håkan Jacobsson [mailto:hakan.jacobsson@aftonbladet.se]
> Sent: Monday, January 04, 2010 10:58 AM
> To: interest@jai.dev.java.net
> Subject: [JAI] Image cropping to fixed width and height
>
> Hi,
>
> I want to use JAI to resize and crop JPEG/GIF images. I need the final
> images to share the same width and height.
> So, I think, firstly I should resize the original image (of any size)
> - keeping the proportions intact. And after this first step
> I want to end up having an image with the best possible 'match' to the
> width and height I want for my final image (as close as possible).
> Secondly, I want to crop the image and end up with the final image -
> having the width and height I intended for it.
> I also would like to have an option for where the cropping should
> ocurr. Left upper corner, right upper corner or in the centre.
>
> Is this possible? I'd very grateful for help with this.
>
> /best regards, Håkan Jacobsson - Java developer in Stockholm, Sweden
>
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
> For additional commands, e-mail: interest-help@jai.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net

Håkan Jacobsson

Hi,

How do I ensure the border is coloured white? I don't understand the
BorderExtensionConstant?

/best regards, Håkan
---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@jai.dev.java.net
For additional commands, e-mail: interest-help@jai.dev.java.net