How to Setsize of Image Using Rescaleop

How to setSize of image using RescaleOp

First filter(), as shown here, and then scale using drawImage() or AffineTransformOp, as shown here.

Addendum: Alternatively, you can scale the image first (using either approach above) and then use your RescaleOp in drawImage().

As an aside, RescaleOp scales the image's color bands; it does not change the image's dimensions. To avoid confusion, dimensional scaling is sometimes called resampling.

Addendum: Here's an example of using drawImage() to resample and RescaleOp to adjust the alpha of an image.

Sample Image

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
* @see https://stackoverflow.com/questions/5838842
* @see https://stackoverflow.com/questions/5864490
*/
public class AlphaTest {

private static void display() {
JFrame f = new JFrame("AlphaTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

ImageIcon icon = new ImageIcon("image.jpg");
final AlphaPanel ip = new AlphaPanel(icon, 0.75);
final JSlider slider = new JSlider();
slider.addChangeListener(new ChangeListener() {

@Override
public void stateChanged(ChangeEvent e) {
int v = slider.getValue();
ip.setAlpha((float) v / slider.getMaximum());
ip.repaint();
}
});
f.add(ip, BorderLayout.CENTER);
f.add(slider, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
display();
}
});
}
}

class AlphaPanel extends JPanel {

private BufferedImage bi;
private float[] scales = {1f, 1f, 1f, 0.5f};
private float[] offsets = new float[4];
private RescaleOp rop;

public AlphaPanel(ImageIcon icon, double scale) {

int width = (int) (scale * icon.getIconWidth());
int height = (int) (scale * icon.getIconHeight());
this.setPreferredSize(new Dimension(width, height));
this.bi = new BufferedImage(
width, height, BufferedImage.TYPE_INT_ARGB);
this.bi.createGraphics().drawImage(
icon.getImage(), 0, 0, width, height, null);
rop = new RescaleOp(scales, offsets, null);
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(bi, rop, 0, 0);
}

public void setAlpha(float alpha) {
this.scales[3] = alpha;
this.rop = new RescaleOp(scales, offsets, null);
}
}

Java Buffered Image RescaleOp Transparency Issue

You could try the RescaleOp that handles alpha, illustrated here, and use the same lightLevel for all color components.

How to scale a BufferedImage

AffineTransformOp offers the additional flexibility of choosing the interpolation type.

BufferedImage before = getBufferedImage(encoded);
int w = before.getWidth();
int h = before.getHeight();
BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
AffineTransform at = new AffineTransform();
at.scale(2.0, 2.0);
AffineTransformOp scaleOp =
new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
after = scaleOp.filter(before, after);

The fragment shown illustrates resampling, not cropping; this related answer addresses the issue; some related examples are examined here.

Changing contrast of image with alpha channel causes yellow tint

I fixed the issue by updating to Java 9.

This seems to be a bug in Java 8, that is now fixed in Java 9. I originally used JDK1.8.0_144 and received the yellow tint, I now use JDK-9.0.4 and no longer have the issue. Now the image looks the same with and without alpha channel.

java.lang.IllegalArgumentException: Number of scaling constants does not equal the number of of color or color/alpha components

Using the example below and the image you provided, I am unable to reproduce the effect you describe.

I was puzzled that a BufferedImage of TYPE_4BYTE_ABGR_PRE has a ComponentColorModel, in contrast to the more familiar DirectColorModel, but it's an IndexColorModel that cannot be rescaled.

Addendum: Updated code to use filter(), as the previous version was incorrectly reusing the BufferedImage.

Addendum: In another answer, you said,

I don't want to create a new BufferedImage each time. I want to filter the image on the fly using a JSlider.

The example you cited does this by creating the BufferedImage once in the SeeThroughComponent constructor and then adjusting just the RescaleOp in the slider's change handler. It seems quite responsive.

Addendum: In an edit to your question, you mention that the IllegalArgumentException may arise when encountering an image having an IndexColorModel. I am able to reproduce this using, e.g. TYPE_BYTE_INDEXED. You may be able to work around such images by trapping the exception and rendering them separately as shown here.

Sample Image

import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/questions/5838842 */
public class RescaleOpTest extends JPanel {

public static final String LINK =
"http://www.freeimagehosting.net/uploads/576c64ef7b.png";

public RescaleOpTest() {
this.setLayout(new GridLayout(1, 0));
Image img = null;
try {
img = ImageIO.read(new URL(LINK));
// img = ImageIO.read(new File("image.jpg"));
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
int w = img.getWidth(null);
int h = img.getHeight(null);
BufferedImage bi = new BufferedImage(
w, h, BufferedImage.TYPE_4BYTE_ABGR_PRE);
Graphics2D g = bi.createGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();

/* Create a rescale filter op that makes the image 75% opaque */
float[] scales = {1f, 1f, 1f, 0.75f};
float[] offsets = new float[4];
RescaleOp rop = new RescaleOp(scales, offsets, null);
bi = rop.filter(bi, null);
this.add(new JLabel(new ImageIcon(img)));
this.add(new JLabel(new ImageIcon(bi)));
}

private void display() {
JFrame f = new JFrame("RescaleOpTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
new RescaleOpTest().display();
}
});
}
}

How to change the brightness of an Image

The doc says:

The pseudo code for the rescaling operation is as follows:

for each pixel from Source object {
for each band/component of the pixel {
dstElement = (srcElement*scaleFactor) + offset
}
}

It's just a linear transformation on every pixel. The parameters for that transformation are scaleFactor and offset. If you want 100% brightness, this transform must be an identity, i.e. dstElement = srcElement. Setting scaleFactor = 1 and offset = 0 does the trick.

Now suppose you want to make the image darker, at 75% brightness like you say. That amounts to multiplying the pixel values by 0.75. You want: dstElement = 0.75 * srcElement. So setting scaleFactor = 0.75 and offset = 0 should do the trick. The problem with your values is that they go from 0 to 100, you need to use values between 0 and 1.



Related Topics



Leave a reply



Submit