-
Reflection of image.
in trying out to reflect an image after turning B/W, the reflected image has a rectangular block of black pixels at the bottom.. i have played with the code for a long time. but unable to get it right.. can anyone have a look.. code is pretty screwed up . iguess. consider it 4 now.
Code:
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
public class Reflect extends JComponent {
private BufferedImage image;
public Reflect() {
try {
image = ImageIO.read( new File( "/home/sandeep/Desktop/visit.gif" ) );
}
catch ( Exception e ) {
e.printStackTrace();
}
}
public void paintComponent( Graphics g ) {
Graphics2D g2d = (Graphics2D)g;
int width = getWidth();
int height = getHeight();
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
int gap = 20;
float opacity = 0.4f;
float fadeHeight = 0.3f;
g2d.setPaint( new GradientPaint( 0, 0, Color.black, 0, height, Color.darkGray ) );
g2d.fillRect( 0, 0, width, height );
g2d.translate( (width-imageWidth)/2, height/2-imageHeight );
g2d.drawRenderedImage( image, null );
g2d.translate( 0, 2*imageHeight+gap );
g2d.scale( 1, -1 );
BufferedImage reflection = new BufferedImage( imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB );
try {
reflection = BlackWhite();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Graphics2D rg = reflection.createGraphics();
rg.drawRenderedImage( image, null );
rg.setComposite( AlphaComposite.getInstance( AlphaComposite.DST_IN ) );
rg.setPaint(
new GradientPaint(
0, imageHeight*fadeHeight, new Color( 0.0f, 0.0f, 0.0f, 0.0f ),
0, imageHeight, new Color( 0.0f, 0.0f, 0.0f, opacity )
)
);
rg.fillRect( 0, 0, imageWidth, imageHeight );
rg.dispose();
g2d.drawRenderedImage( reflection, null );
}
public BufferedImage BlackWhite() throws IOException {
// Create a binary image for the results of processing
//File img_file = new File(path);
//BufferedImage FROM THE IMAGE READ AT URL.
// image = ImageIO.read(img_file);
int w = image.getWidth();
int h = image.getHeight();
BufferedImage outputImage = new BufferedImage(w, h,
BufferedImage.TYPE_BYTE_BINARY);
// Work on a copy of input image because it is modified by diffusion
WritableRaster input = image.copyData(null);
WritableRaster output = outputImage.getRaster();
final int threshold = 128;
float value, error;
for (int y = 0; y < h; ++y)
for (int x = 0; x < w; ++x) {
value = input.getSample(x, y, 0);
// Threshold value and compute error
if (value < threshold) {
output.setSample(x, y, 0, 0);
error = value;
}
else {
output.setSample(x, y, 0, 1);
error = value - 255;
}
// Spread error amongst neighbouring pixels
if((x > 0) && (y > 0) && (x < (w-1)) && (y < (h-1)))
{
value = input.getSample(x+1, y, 0);
input.setSample(x+1, y, 0, clamp(value + 0.4375f * error));
value = input.getSample(x-1, y+1, 0);
input.setSample(x-1, y+1, 0, clamp(value + 0.1875f * error));
value = input.getSample(x, y+1, 0);
input.setSample(x, y+1, 0, clamp(value + 0.3125f * error));
value = input.getSample(x+1, y+1, 0);
input.setSample(x+1, y+1, 0, clamp(value + 0.0625f * error));
}
}
return outputImage;
}
// Forces a value to a 0-255 integer range
public static int clamp(float value) {
return Math.min(Math.max(Math.round(value), 0), 255);
}
//conversion function into black and white ends.
public Dimension getPreferredSize() {
return new Dimension( 700, 700 );
}
public static void main (String args[]) {
JFrame f = new JFrame();
Reflect r = new Reflect();
f.getContentPane().add( r );
f.pack();
f.show();
}
}
-
I'm not sure what's wrong with your code, but I would consider approaching things a little differently. First off, you really don't want to create a new BufferedImage within the paintComponent method. It won't correct your underlying problem, but regardless, this code is unnecessarily redundant and will slow your painting down.
Next, while I am certainly no pro at this, I believe that you can convert an image to grey-scale using a ColorConvertOp object's filter method. The ColorConvertOp object can be created with a ColorSpace object derived via ColorSpace.getInstance(ColorSpace.CS_GRAY);
Then you can reflect the image with an AffineTransform or two.
-
For example:
Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class ReflectB {
private static final String IMAGE_PATH = "http://duke.kenai.com/gun/Gun.jpg";
private JPanel mainPanel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
createPanelBackground(g);
}
};
public ReflectB(BufferedImage image) {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
ColorSpace bwColorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp convert = new ColorConvertOp(bwColorSpace, null);
BufferedImage bwImage = convert.filter(image, null);
AffineTransform flipAT = AffineTransform.getScaleInstance(1, -1);
flipAT.translate(0, -imageHeight);
AffineTransformOp transformOp = new AffineTransformOp(flipAT, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
BufferedImage reflectedImage = transformOp.filter(bwImage, null);
ImageIcon icon = new ImageIcon(image);
ImageIcon reflectedIcon = new ImageIcon(reflectedImage);
JLabel label = new JLabel(icon);
JLabel reflectedLabel = new JLabel(reflectedIcon);
int gap = 20;
mainPanel.setBorder(BorderFactory.createEmptyBorder(2 * gap, 4 * gap, 2 * gap, 4 * gap));
mainPanel.setLayout(new BorderLayout(0, gap));
mainPanel.add(label, BorderLayout.NORTH);
mainPanel.add(reflectedLabel, BorderLayout.SOUTH);
}
private void createPanelBackground(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(new GradientPaint(0, 0, Color.black, 0, mainPanel.getHeight(), Color.lightGray));
g2d.fillRect(0, 0, mainPanel.getWidth(), mainPanel.getHeight());
}
public JPanel getMainPanel() {
return mainPanel;
}
private static void createAndShowUI() {
BufferedImage image = null;
try {
image = ImageIO.read(new URL(IMAGE_PATH));
} catch (Exception e) {
e.printStackTrace();
}
JFrame frame = new JFrame("Reflected Image");
frame.getContentPane().add(new ReflectB(image).getMainPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
-