Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #36432 > unrolled thread
| Started by | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| First post | 2017-04-12 10:34 +0200 |
| Last post | 2017-04-12 16:13 +0000 |
| Articles | 8 — 4 participants |
Back to article view | Back to comp.lang.java.programmer
Can you resize with BufferedImage Cecil Westerhof <Cecil@decebal.nl> - 2017-04-12 10:34 +0200
Re: Can you resize with BufferedImage Martin Gregorie <martin@address-in-sig.invalid> - 2017-04-12 10:18 +0000
Re: Can you resize with BufferedImage Cecil Westerhof <Cecil@decebal.nl> - 2017-04-12 14:08 +0200
Re: Can you resize with BufferedImage Martin Gregorie <martin@address-in-sig.invalid> - 2017-04-12 13:06 +0000
Re: Can you resize with BufferedImage Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-04-12 10:05 -0500
Re: Can you resize with BufferedImage Eric Douglas <e.d.programmer@gmail.com> - 2017-04-12 08:20 -0700
Re: Can you resize with BufferedImage Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-04-13 11:10 -0500
Re: Can you resize with BufferedImage Martin Gregorie <martin@address-in-sig.invalid> - 2017-04-12 16:13 +0000
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2017-04-12 10:34 +0200 |
| Subject | Can you resize with BufferedImage |
| Message-ID | <871ssy10ub.fsf@Equus.decebal.nl> |
In my code I have the following code:
dest = image.getSubimage(x, y, dispWidth, dispHeight);
This is the part that I want to select, but I want to resize it at the
same time. In this case I would like to scale to 50%.
How should I do that?
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
[toc] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2017-04-12 10:18 +0000 |
| Message-ID | <ockuu9$oh6$1@dont-email.me> |
| In reply to | #36432 |
On Wed, 12 Apr 2017 10:34:04 +0200, Cecil Westerhof wrote:
> In my code I have the following code:
> dest = image.getSubimage(x, y, dispWidth, dispHeight);
>
> This is the part that I want to select, but I want to resize it at the
> same time. In this case I would like to scale to 50%.
> How should I do that?
Use an AffineTransform.
The image resizing code should look something like this fragment:
AffineTransform at = new AffineTransform();
at.scale(scale, scale);
AffineTransformOp op = new AffineTransformOp(at,
AffineTransformOp.TYPE_BICUBIC);
Double nw = new Double(w * scale);
Double nh = new Double(h * scale);
om = new BufferedImage(nw.intValue(),
nh.intValue(),
BufferedImage.TYPE_3BYTE_BGR);
op.filter(im, om);
where:
im is a BufferedImage containing the old image
om is a BufferedImage to hold the modified image
scale is a double containing the required scaling factor
I'm scaling images to a width of 400 pixels, so I calculate scale as
400.0 / image_width. You would just set scale to 0.5. I want to keep the
image proportion, so I use the same scale value for both width and height.
--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
[toc] | [prev] | [next] | [standalone]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2017-04-12 14:08 +0200 |
| Message-ID | <87wpapzv42.fsf@Equus.decebal.nl> |
| In reply to | #36433 |
On Wednesday 12 Apr 2017 12:18 CEST, Martin Gregorie wrote: > On Wed, 12 Apr 2017 10:34:04 +0200, Cecil Westerhof wrote: > >> In my code I have the following code: >> dest = image.getSubimage(x, y, dispWidth, dispHeight); >> >> This is the part that I want to select, but I want to resize it at >> the same time. In this case I would like to scale to 50%. How >> should I do that? > > Use an AffineTransform. > > The image resizing code should look something like this fragment: > > AffineTransform at = new AffineTransform(); > at.scale(scale, scale); > AffineTransformOp op = new AffineTransformOp(at, > AffineTransformOp.TYPE_BICUBIC); > Double nw = new Double(w * scale); > Double nh = new Double(h * scale); > om = new BufferedImage(nw.intValue(), > nh.intValue(), > BufferedImage.TYPE_3BYTE_BGR); > op.filter(im, om); > > where: > im is a BufferedImage containing the old image > om is a BufferedImage to hold the modified image > scale is a double containing the required scaling factor > > I'm scaling images to a width of 400 pixels, so I calculate scale as > 400.0 / image_width. You would just set scale to 0.5. I want to keep > the image proportion, so I use the same scale value for both width > and height. Does not look to difficult. Just to be sure I understand it correctly. I first cut the part I want and then I do the scale. So my dest becomes im. And then I use your code. -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2017-04-12 13:06 +0000 |
| Message-ID | <ocl8os$qc7$1@dont-email.me> |
| In reply to | #36434 |
On Wed, 12 Apr 2017 14:08:29 +0200, Cecil Westerhof wrote: > On Wednesday 12 Apr 2017 12:18 CEST, Martin Gregorie wrote: > >> On Wed, 12 Apr 2017 10:34:04 +0200, Cecil Westerhof wrote: >> >>> In my code I have the following code: >>> dest = image.getSubimage(x, y, dispWidth, dispHeight); >>> >>> This is the part that I want to select, but I want to resize it at the >>> same time. In this case I would like to scale to 50%. How should I do >>> that? >> >> Use an AffineTransform. >> >> The image resizing code should look something like this fragment: >> >> AffineTransform at = new AffineTransform(); >> at.scale(scale, scale); >> AffineTransformOp op = new AffineTransformOp(at, >> AffineTransformOp.TYPE_BICUBIC); >> Double nw = new Double(w * scale); >> Double nh = new Double(h * scale); >> om = new BufferedImage(nw.intValue(), >> nh.intValue(), >> BufferedImage.TYPE_3BYTE_BGR); >> op.filter(im, om); >> >> where: >> im is a BufferedImage containing the old image om is a >> BufferedImage to hold the modified image scale is a double containing >> the required scaling factor >> >> I'm scaling images to a width of 400 pixels, so I calculate scale as >> 400.0 / image_width. You would just set scale to 0.5. I want to keep >> the image proportion, so I use the same scale value for both width and >> height. > > Does not look to difficult. Just to be sure I understand it correctly. > I first cut the part I want and then I do the scale. So my dest becomes > im. And then I use your code. That sounds right - first select what you want to have in the image and then scale it to whatever size you want. I don't remember where I would have found the example code that became what I published, but I do remember going to look for it once I realised that the Java tutorials, package and class-level comments was absolutely bloody useless when it comes to explaining how to choose the classes you'll need to carry out a task or the best order to apply them in. They make the unstated assumption that any programmer who needs to use the classes in java.awt.image and java.awt.image.renderable will already understand everything they need to know about the purpose of the classes they contain and which ones to use for any given task. I, for one, don't have an image processing background apart from being a self-taught GIMP user and, on the face of it, nor does Cecil, so if anybody reading this can recommend a book or a website that covers the basics of programming with these tools, please post the link here. Speaking entirely for myself, something with the approach and content of the better O'Reilly books would be perfect. -- martin@ | Martin Gregorie gregorie. | Essex, UK org |
[toc] | [prev] | [next] | [standalone]
| From | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| Date | 2017-04-12 10:05 -0500 |
| Message-ID | <oclfir$p3p$1@dont-email.me> |
| In reply to | #36438 |
On 4/12/2017 08:06, Martin Gregorie wrote:
If you find a good book, let us all know please.
I wrote a library to do a few common image mods so I don't have to
remember how to do it every time:
package com.knutejohnson.classes;
import java.awt.*;
import java.awt.color.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.imageio.stream.*;
import javax.imageio.plugins.jpeg.*;
/**
* ImageUtilities is an assortment of static methods to manipulate
* BufferedImages
*
* @author Knute Johnson
*/
public class ImageUtilities {
/**
* Writes a BufferedImage to a JPEG file with the specified quality
*
* @param image BufferedImage to write
* @param quality image quality, a float value between 0.0f and 1.0f
* @param file destination File
*
* @throws IOException if an error occurs writing to the file
* @throws IllegalArgumentException if quality is not in the range
* 0.0f to 1.0f
*/
public static void writeJPEG(RenderedImage image, float quality,
File file)
throws IOException {
if (quality < 0.0f || quality > 1.0f)
throw new IllegalArgumentException("0.0 < Quality < 1.0");
ImageWriter writer = null;
Iterator iter = ImageIO.getImageWritersByFormatName("JPEG");
if (!iter.hasNext())
throw new IOException("No Writers Available");
writer = (ImageWriter)iter.next();
if (file.exists())
file.delete();
ImageOutputStream ios = ImageIO.createImageOutputStream(file);
writer.setOutput(ios);
JPEGImageWriteParam iwp = new JPEGImageWriteParam(null);
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(quality);
writer.write(null,new IIOImage(image,null,null),iwp);
ios.flush();
writer.dispose();
ios.close();
}
/**
* Converts a colored image to gray scale
*
* @param image source BufferedImage
* @param hints any rendering hints for the conversion or
{@code null}
*
* @return gray scale BufferedImage
*/
public static BufferedImage convertToGray(BufferedImage image,
RenderingHints hints) {
BufferedImage gray =
createCompatible(image.getWidth(),image.getHeight());
ColorConvertOp op = new ColorConvertOp(
image.getColorModel().getColorSpace(),
ColorSpace.getInstance(ColorSpace.CS_GRAY),hints);
return op.filter(image,gray);
}
/**
* Converts a color image to sepia tone
*
* @param image source image
* @param hints any rendering hints for the conversion or
{@code null}
*
* @return sepia tone image
*/
public static BufferedImage convertToSepia(BufferedImage image,
RenderingHints hints) {
BufferedImage sepia =
createCompatible(image.getWidth(),image.getHeight());
// convert to grayscale and back to compatible RGB
ColorSpace imgCS = image.getColorModel().getColorSpace();
ColorSpace grayCS = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorSpace sepiaCS = sepia.getColorModel().getColorSpace();
ColorConvertOp cop = new ColorConvertOp(imgCS,grayCS,hints);
image = cop.filter(image,null);
cop = new ColorConvertOp(grayCS,sepiaCS,hints);
sepia = cop.filter(image,null);
// slightly enhance the red, slightly reduce the green and
// remove half the blue
float[] factor = new float[] { 1.35f,1f,.7f };
float[] offset = new float[] { 0f,0f,0f };
RescaleOp rop = new RescaleOp(factor,offset,hints);
return rop.filter(sepia,null);
}
/**
* Scales a BufferedImage
*
* @param src source BufferedImage
* @param sx x scale factor
* @param sy y scale factor
* @param interpolationType the interpolation type
*
* @return scaled BufferedImage
*
* @see AffineTransformOp
*/
public static BufferedImage scaleImage(BufferedImage src, double sx,
double sy, int interpolationType) {
AffineTransformOp op = new AffineTransformOp(
AffineTransform.getScaleInstance(sx,sy),interpolationType);
return op.filter(src,null);
}
/**
* Scales a BufferedImage
*
* @param src source BufferedImage
* @param sx x scale factor
* @param sy y scale factor
* @param hints any rendering hints or {@code null}
*
* @return scaled BufferedImage
*
* @see RenderingHints
*/
public static BufferedImage scaleImage(BufferedImage src, double sx,
double sy, RenderingHints hints) {
AffineTransformOp op = new AffineTransformOp(
AffineTransform.getScaleInstance(sx,sy),hints);
return op.filter(src,null);
}
/**
* Creates a compatible BufferedImage with the specified dimensions
*
* @param width width of the image
* @param height height of the image
*
* @return compatible BufferedImage
*/
public static BufferedImage createCompatible(int width, int height) {
GraphicsConfiguration gc = getDefaultConfiguration();
return gc.createCompatibleImage(width,height);
}
/**
* Creates a compatible BufferedImage with the specified dimensions and
* transparency
*
* @param width image width
* @param height image height
* @param transparency transparency of the image
*
* @return compatible BufferedImage
*
* @see BufferedImage
* @see Transparency
*/
public static BufferedImage createCompatible(int width, int height,
int transparency) {
GraphicsConfiguration gc = getDefaultConfiguration();
return gc.createCompatibleImage(width,height,transparency);
}
/**
* Converts an existing image to a compatible ColorModel
*
* @param image source BufferedImage
* @param hints any RenderingHints or {@code null}
*
* @return compatible BufferedImage
*
* @see ColorModel
* @see RenderingHints
*/
public static BufferedImage convertToCompatible(BufferedImage image,
RenderingHints hints) {
if (isCompatible(image))
return image;
ColorConvertOp op = new ColorConvertOp(
image.getColorModel().getColorSpace(),
getDefaultConfiguration().getColorModel().getColorSpace(),hints);
return op.filter(image,null);
}
/**
* Converts an existing BufferedImage to a compatible ColorModel
*
* @param image source BufferedImage
*
* @return compatible BufferedImage
*/
public static BufferedImage convertToCompatible(BufferedImage image) {
return convertToCompatible(image,null);
}
/**
* Checks if a BufferedImage is compatible
*
* @param src source BufferedImage
*
* @return {@code true} if image is compatible
*/
public static boolean isCompatible(BufferedImage src) {
GraphicsConfiguration gc = getDefaultConfiguration();
return src.getColorModel().equals(gc.getColorModel());
}
/**
* Gets the default graphics configuration. Used by several methods in
* this class.
*
* @return default graphics configuration
*/
public static GraphicsConfiguration getDefaultConfiguration() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
}
}
--
Knute Johnson
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-04-12 08:20 -0700 |
| Message-ID | <2c781f24-6e80-4e00-b8db-cb507c2b2993@googlegroups.com> |
| In reply to | #36439 |
On Wednesday, April 12, 2017 at 11:06:08 AM UTC-4, Knute Johnson wrote:
> On 4/12/2017 08:06, Martin Gregorie wrote:
>
> If you find a good book, let us all know please.
>
> I wrote a library to do a few common image mods so I don't have to
> remember how to do it every time:
>
> package com.knutejohnson.classes;
>
> import java.awt.*;
> import java.awt.color.*;
> import java.awt.geom.*;
> import java.awt.image.*;
> import java.io.*;
> import java.util.*;
> import javax.imageio.*;
> import javax.imageio.stream.*;
> import javax.imageio.plugins.jpeg.*;
>
> /**
> * ImageUtilities is an assortment of static methods to manipulate
> * BufferedImages
> *
> * @author Knute Johnson
> */
> public class ImageUtilities {
> /**
> * Writes a BufferedImage to a JPEG file with the specified quality
> *
> * @param image BufferedImage to write
> * @param quality image quality, a float value between 0.0f and 1.0f
> * @param file destination File
> *
> * @throws IOException if an error occurs writing to the file
> * @throws IllegalArgumentException if quality is not in the range
> * 0.0f to 1.0f
> */
> public static void writeJPEG(RenderedImage image, float quality,
> File file)
> throws IOException {
> if (quality < 0.0f || quality > 1.0f)
> throw new IllegalArgumentException("0.0 < Quality < 1.0");
> ImageWriter writer = null;
> Iterator iter = ImageIO.getImageWritersByFormatName("JPEG");
> if (!iter.hasNext())
> throw new IOException("No Writers Available");
> writer = (ImageWriter)iter.next();
> if (file.exists())
> file.delete();
> ImageOutputStream ios = ImageIO.createImageOutputStream(file);
> writer.setOutput(ios);
> JPEGImageWriteParam iwp = new JPEGImageWriteParam(null);
> iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
> iwp.setCompressionQuality(quality);
> writer.write(null,new IIOImage(image,null,null),iwp);
> ios.flush();
> writer.dispose();
> ios.close();
> }
>
> /**
> * Converts a colored image to gray scale
> *
> * @param image source BufferedImage
> * @param hints any rendering hints for the conversion or
> {@code null}
> *
> * @return gray scale BufferedImage
> */
> public static BufferedImage convertToGray(BufferedImage image,
> RenderingHints hints) {
> BufferedImage gray =
> createCompatible(image.getWidth(),image.getHeight());
>
> ColorConvertOp op = new ColorConvertOp(
> image.getColorModel().getColorSpace(),
> ColorSpace.getInstance(ColorSpace.CS_GRAY),hints);
>
> return op.filter(image,gray);
> }
>
> /**
> * Converts a color image to sepia tone
> *
> * @param image source image
> * @param hints any rendering hints for the conversion or
> {@code null}
> *
> * @return sepia tone image
> */
> public static BufferedImage convertToSepia(BufferedImage image,
> RenderingHints hints) {
> BufferedImage sepia =
> createCompatible(image.getWidth(),image.getHeight());
>
> // convert to grayscale and back to compatible RGB
> ColorSpace imgCS = image.getColorModel().getColorSpace();
> ColorSpace grayCS = ColorSpace.getInstance(ColorSpace.CS_GRAY);
> ColorSpace sepiaCS = sepia.getColorModel().getColorSpace();
> ColorConvertOp cop = new ColorConvertOp(imgCS,grayCS,hints);
> image = cop.filter(image,null);
> cop = new ColorConvertOp(grayCS,sepiaCS,hints);
> sepia = cop.filter(image,null);
>
> // slightly enhance the red, slightly reduce the green and
> // remove half the blue
> float[] factor = new float[] { 1.35f,1f,.7f };
> float[] offset = new float[] { 0f,0f,0f };
> RescaleOp rop = new RescaleOp(factor,offset,hints);
>
> return rop.filter(sepia,null);
> }
>
> /**
> * Scales a BufferedImage
> *
> * @param src source BufferedImage
> * @param sx x scale factor
> * @param sy y scale factor
> * @param interpolationType the interpolation type
> *
> * @return scaled BufferedImage
> *
> * @see AffineTransformOp
> */
> public static BufferedImage scaleImage(BufferedImage src, double sx,
> double sy, int interpolationType) {
> AffineTransformOp op = new AffineTransformOp(
> AffineTransform.getScaleInstance(sx,sy),interpolationType);
>
> return op.filter(src,null);
> }
>
> /**
> * Scales a BufferedImage
> *
> * @param src source BufferedImage
> * @param sx x scale factor
> * @param sy y scale factor
> * @param hints any rendering hints or {@code null}
> *
> * @return scaled BufferedImage
> *
> * @see RenderingHints
> */
> public static BufferedImage scaleImage(BufferedImage src, double sx,
> double sy, RenderingHints hints) {
> AffineTransformOp op = new AffineTransformOp(
> AffineTransform.getScaleInstance(sx,sy),hints);
>
> return op.filter(src,null);
> }
>
> /**
> * Creates a compatible BufferedImage with the specified dimensions
> *
> * @param width width of the image
> * @param height height of the image
> *
> * @return compatible BufferedImage
> */
> public static BufferedImage createCompatible(int width, int height) {
> GraphicsConfiguration gc = getDefaultConfiguration();
>
> return gc.createCompatibleImage(width,height);
> }
>
> /**
> * Creates a compatible BufferedImage with the specified dimensions and
> * transparency
> *
> * @param width image width
> * @param height image height
> * @param transparency transparency of the image
> *
> * @return compatible BufferedImage
> *
> * @see BufferedImage
> * @see Transparency
> */
> public static BufferedImage createCompatible(int width, int height,
> int transparency) {
> GraphicsConfiguration gc = getDefaultConfiguration();
>
> return gc.createCompatibleImage(width,height,transparency);
> }
>
> /**
> * Converts an existing image to a compatible ColorModel
> *
> * @param image source BufferedImage
> * @param hints any RenderingHints or {@code null}
> *
> * @return compatible BufferedImage
> *
> * @see ColorModel
> * @see RenderingHints
> */
> public static BufferedImage convertToCompatible(BufferedImage image,
> RenderingHints hints) {
> if (isCompatible(image))
> return image;
>
> ColorConvertOp op = new ColorConvertOp(
> image.getColorModel().getColorSpace(),
> getDefaultConfiguration().getColorModel().getColorSpace(),hints);
>
> return op.filter(image,null);
> }
>
> /**
> * Converts an existing BufferedImage to a compatible ColorModel
> *
> * @param image source BufferedImage
> *
> * @return compatible BufferedImage
> */
> public static BufferedImage convertToCompatible(BufferedImage image) {
> return convertToCompatible(image,null);
> }
>
> /**
> * Checks if a BufferedImage is compatible
> *
> * @param src source BufferedImage
> *
> * @return {@code true} if image is compatible
> */
> public static boolean isCompatible(BufferedImage src) {
> GraphicsConfiguration gc = getDefaultConfiguration();
>
> return src.getColorModel().equals(gc.getColorModel());
> }
>
> /**
> * Gets the default graphics configuration. Used by several methods in
> * this class.
> *
> * @return default graphics configuration
> */
> public static GraphicsConfiguration getDefaultConfiguration() {
> return GraphicsEnvironment.getLocalGraphicsEnvironment().
> getDefaultScreenDevice().getDefaultConfiguration();
> }
> }
>
>
>
> --
>
> Knute Johnson
I've never used an AffineTransformOp.
To change the size of an image I just generate a new image of the width/height/transparency I want. Then I get the Graphics of the new image, cast it to a Graphics2D, create a new AffineTransform, and set the translate/scale/rotate I want. Then I call .setComposite(AlphaComposite.SrcOver) on the new image's Graphics2D, then just .drawImage() passing in the old image, the AffineTransform I just created, and the observer (normally null).
Normally you want to maintain proportions, your x and y for the scale are both Math.min(newWidth / originalImageWidth, newHeight / originalImageHeight).
[toc] | [prev] | [next] | [standalone]
| From | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| Date | 2017-04-13 11:10 -0500 |
| Message-ID | <oco7n7$n8$1@dont-email.me> |
| In reply to | #36440 |
On 4/12/2017 10:20, Eric Douglas wrote: > > I've never used an AffineTransformOp. To change the size of an image > I just generate a new image of the width/height/transparency I want. > Then I get the Graphics of the new image, cast it to a Graphics2D, > create a new AffineTransform, and set the translate/scale/rotate I > want. Then I call .setComposite(AlphaComposite.SrcOver) on the new > image's Graphics2D, then just .drawImage() passing in the old image, > the AffineTransform I just created, and the observer (normally > null). > > Normally you want to maintain proportions, your x and y for the scale > are both Math.min(newWidth / originalImageWidth, newHeight / > originalImageHeight). > I've done it that way too. I don't really know which is faster. -- Knute Johnson
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2017-04-12 16:13 +0000 |
| Message-ID | <ocljna$vbj$1@dont-email.me> |
| In reply to | #36439 |
On Wed, 12 Apr 2017 10:05:54 -0500, Knute Johnson wrote: > On 4/12/2017 08:06, Martin Gregorie wrote: > > If you find a good book, let us all know please. > > I wrote a library to do a few common image mods so I don't have to > remember how to do it every time: > > package com.knutejohnson.classes; Useful stuff. Thanks for posting it. -- martin@ | Martin Gregorie gregorie. | Essex, UK org |
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web