0

I am trying to read an image, zoom it in to 80*60 and then make it duplicated in size by replication method. My methods work well individually, but when when I call them in the main method my image turns black. Can anyone help me please? Here is my code :

import java.awt.BorderLayout;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        BufferedImage Image = null;
        File fc = null;

          try{

              fc = new File("C:\\1.jpg");
              Image = ImageIO.read(fc);
              BufferedImage zoomin = new BufferedImage(ScaledImage(Image,80,60).getWidth(null),ScaledImage(Image,80,60).getWidth(null), BufferedImage.TYPE_BYTE_GRAY);
              JFrame frame = new JFrame("Scaled Resolution");
              frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
              JLabel lbl = new JLabel();
                lbl.setIcon(new  ImageIcon(ImgReplication(zoomin,2)));
                frame.getContentPane().add(lbl, BorderLayout.CENTER);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

          }
          catch (Exception e1){
            System.out.println(e1);
            } 


    }
public static BufferedImage ImgReplication(BufferedImage image, int n) {

        int w = n * image.getWidth();
        int h = n * image.getHeight();

        BufferedImage enlargedImage =
                new BufferedImage(w, h, image.getType());

        for (int y=0; y < h; ++y)
            for (int x=0; x < w; ++x)
                enlargedImage.setRGB(x, y, image.getRGB(x/n, y/n));

        return enlargedImage;

    }
public static BufferedImage ScaledImage(Image img, int w , int h){

    BufferedImage resizedImage = new BufferedImage(w , h , BufferedImage.TYPE_BYTE_GRAY);
    Graphics2D g2 = resizedImage.createGraphics();
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g2.drawImage(img, 0, 0, w, h, null);
    g2.dispose();
    return resizedImage;
}


}
Nazi
  • 61
  • 10
  • Are you taking into consideration the alpha channel? – Jonathan Eustace Apr 23 '16 at 17:22
  • works well individually? where at which point do you draw the image and it works well? – gpasch Apr 23 '16 at 17:51
  • The image that I am supposed to read is gray scaled BYTE. I don't have alpha. – Nazi Apr 23 '16 at 18:47
  • And yes, each method works individually in another program that I am working on . I mean I can resize an image to my desired scale using ScaledImage() and I can enlarge my image by ImgReplication method. However, when I try to call them in my main method the image that i get is black . Problem comes from this line :BufferedImage zoomin = new BufferedImage(ScaledImage(Image,80,60).getWidth(null),ScaledImage(Image,80,60).getWidth(null), BufferedImage.TYPE_BYTE_GRAY); – Nazi Apr 23 '16 at 18:51
  • The point is I don't want to show the scaledImage to user or save it somewhere. I just want to show the enlarged Image to show how the picture's resolution will change using zoom by Replication method. – Nazi Apr 23 '16 at 18:55
  • you need to try new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); – gpasch Apr 23 '16 at 20:19
  • @gpasch, I tried that but still get the same result. A black enlarged image. :( . – Nazi Apr 23 '16 at 20:35
  • Maybe it's just me, but that seems like a lot of work, something like [this](http://stackoverflow.com/questions/14115950/quality-of-image-after-resize-very-low-java/14116752#14116752) or [this](http://stackoverflow.com/questions/11959758/java-maintaining-aspect-ratio-of-jpanel-background-image/11959928#11959928) might provide some ideas – MadProgrammer Apr 23 '16 at 22:36

2 Answers2

1

What I'm proposing is this:

    BufferedImage Image = null;
    File fc = null;

      try{

          fc = new File("C:\\1.jpg");
          Image = ImageIO.read(fc);
          BufferedImage sc=ScaledImage(Image,80,60);
          JFrame frame = new JFrame("Scaled Resolution");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          JLabel lbl = new JLabel();
            lbl.setIcon(new  ImageIcon(ImgReplication(sc,2)));
            frame.getContentPane().add(lbl, BorderLayout.CENTER);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

      }
      catch (Exception e1){
        System.out.println(e1);
        } 


}

public static BufferedImage ImgReplication(BufferedImage image, int n) {

    int w = n * image.getWidth();
    int h = n * image.getHeight();

    BufferedImage enlargedImage =
            new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

    for (int y=0; y < h; ++y)
        for (int x=0; x < w; ++x)
            enlargedImage.setRGB(x, y, image.getRGB(x/n, y/n));

    return enlargedImage;

}

public static BufferedImage ScaledImage(Image img, int w , int h){

  BufferedImage resizedImage = new BufferedImage(w , h , BufferedImage.TYPE_INT_RGB);
  Graphics2D g2 = resizedImage.createGraphics();
  g2.drawImage(img, 0, 0, w, h, null);
  g2.dispose();
  return resizedImage;
}


}
gpasch
  • 2,672
  • 3
  • 10
  • 12
  • It doesn't make any difference. I still will get the black. I don't know why I am getting this.while everything looks ok to me. Thanks for your effort though.:) – Nazi Apr 23 '16 at 21:17
  • you also missed the correct argument ImgReplication(sc,2) – gpasch Apr 23 '16 at 21:53
  • No, I didn't miss that . here is the line : lbl.setIcon(new ImageIcon(ImgReplication(sc,2))); I know that the problem is coming from calling scaledImage method. Cause everything goes right till hit this line which makes the image black. But I don't understand what is going on. – Nazi Apr 23 '16 at 22:17
1

So, the "core" problem is here...

BufferedImage zoomin = new BufferedImage(
            ScaledImage(Image,80,60).getWidth(null),
            ScaledImage(Image,80,60).getWidth(null), 
            BufferedImage.TYPE_BYTE_GRAY);

All this is doing is creating a blank image which is 80x60 and doing a lot of work to achieve it.

Instead, you should be just using something like...

BufferedImage zoomin = ScaledImage(Image,80,60);

Now, if you want to make it grayscale, then you'd need to make a new BufferedImage image of type BufferedImage.TYPE_BYTE_GRAY of the same size as the zoomin image and paint the zoomin image to it...

You might also like to take a look at Quality of Image after resize very low -- Java and Java: maintaining aspect ratio of JPanel background image for some more ideas about scaling the image. get/setRGB isn't particularly efficient and the quality of drawImage(x, y, w, h) isn't that great either

Runnable example...

So, after making the suggest modifications, I run your algorithms and it came up with this...

Example

Original, ScaledImage, ImgReplication

import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();;
                }
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() throws IOException {
            BufferedImage master = ImageIO.read(new File("..."));
            setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            add(new JLabel(new ImageIcon(master)), gbc);
            add(new JLabel(new ImageIcon(ScaledImage(master, 80, 60))), gbc);
            add(new JLabel(new ImageIcon(ImgReplication(master, 2))), gbc);
        }

    }

    public static BufferedImage ScaledImage(Image img, int w, int h) {

        BufferedImage resizedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
        Graphics2D g2 = resizedImage.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2.drawImage(img, 0, 0, w, h, null);
        g2.dispose();
        return resizedImage;
    }

    public static BufferedImage ImgReplication(BufferedImage image, int n) {

        int w = n * image.getWidth();
        int h = n * image.getHeight();

        BufferedImage enlargedImage
                = new BufferedImage(w, h, image.getType());

        for (int y = 0; y < h; ++y) {
            for (int x = 0; x < w; ++x) {
                enlargedImage.setRGB(x, y, image.getRGB(x / n, y / n));
            }
        }

        return enlargedImage;

    }
}

so it seems to work okay for me

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I have tried what you brought up , but get nothing different . Still an scaled black image. I am not looking for a high quality image though. The main idea of this program is to compare different methods of image interpolations to see which one gives a better image. – Nazi Apr 23 '16 at 23:14
  • The code seems to work fine for me, once I add in the suggested fixes. – MadProgrammer Apr 23 '16 at 23:24
  • 1
    Over 16+ years, I've done a lot of research into image scaling, trying to come up with quick but efficient algorithms [this example](http://stackoverflow.com/questions/14115950/quality-of-image-after-resize-very-low-java/14116752#14116752) and [this example](http://stackoverflow.com/questions/11959758/java-maintaining-aspect-ratio-of-jpanel-background-image/11959928#11959928) are based on simular prinicples which are based on the results from [The Perils of Image.getScaledInstance()](https://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html) and other blogs – MadProgrammer Apr 23 '16 at 23:24
  • 1
    Up scaling is always bad, there's very little you can do about it, if at all possible, always try and down scale – MadProgrammer Apr 23 '16 at 23:25
  • You are such an expert. Thank you so much for all you have done. But my problem came up when I tried to resize the master image to 80*60 and then try to enlarge the resulted image. I mean I could enlarge and resize my original image. But I cannot enlarge the image resulted from resizing. That['s why i was gonna buffer resulting image and then enlarge it.Thank you so much though :) – Nazi Apr 23 '16 at 23:43
  • 1
    So, based on your original code, it was generating a blank image to start with, you should be able to take the example and pass the result of ScaledImage into ImgReplicate directly – MadProgrammer Apr 23 '16 at 23:56
  • 1
    Something like ImgReplication(ScaledImage(master, 80, 60), 2) – MadProgrammer Apr 24 '16 at 00:01
  • Yes! I did it and looks perfectly fine. Thank you so much. But could you please explain me why I got that problem based on your expertise? I do really appreciate it . :) I wish I could give you more stars. :) – Nazi Apr 24 '16 at 00:06
  • 1
    Essentially, your code is just doing BufferedImage zoomin = new BufferedImage(80,60, BufferedImage.TYPE_BYTE_GRAY); – MadProgrammer Apr 24 '16 at 02:29
  • Anyone want to share the reason for the down vote? Does the answer not answer the OPs question? – MadProgrammer Apr 24 '16 at 22:02