Как скопировать данные изображения в подкласс BufferedImage? - PullRequest
0 голосов
/ 11 ноября 2018

У меня есть класс с именем Bitmap, который расширяется от BufferedImage,

public class Bitmap extends BufferedImage {...

Один из его методов, называемых copyImage, который копирует содержимое из исходного изображения в класс, сработал, но этот метод не поддерживает исходное соотношение сторон и размеры исходного изображения.

public void copyImage(Image image) {
    if (image != null) {
        BufferedImage bi = (BufferedImage) image;
        Graphics g = getGraphics();

        g.drawImage(bi, 0, 0, width, height, null);
    }
}

Я хочу, чтобы этот метод скопировал исходное изображение в класс с сохранением его исходного соотношения сторон и размеров. Я подумал о изменении ширины и высоты. Я изменил приведенный выше код так:

public void copyImage(Image image) {
    if (image != null) {
        this.width = image.getWidth(null);
        this.height = image.getWidth(null);

        BufferedImage bi = (BufferedImage) image;
        Graphics g = getGraphics();

        g.drawImage(bi, 0, 0, width, height, null);
    }
}

Но это не сработало, как я могу изменить код выше, чтобы скопировать изображение? Заранее спасибо.

1 Ответ

0 голосов
/ 11 ноября 2018

Это ошибка:

public void copyImage(Image image) {
    if (image != null) {
        this.width = image.getWidth(null);
        this.height = image.getWidth(null);

        BufferedImage bi = (BufferedImage) image;
        Graphics g = getGraphics();

        g.drawImage(bi, 0, 0, width, height, null);
    }
}

Ваши основные проблемы:

  1. Вы, кажется, пытаетесь изменить внутреннюю ширину и высоту исходного изображения, this изображения, и вы не должны этого делать, не так
  2. Вы присваиваете ширину изображения параметра полю this.height с помощью this.height = image.getWidth(null);

Другие вопросы:

  • Вы не экономите ресурсы
  • Вы делаете опасный и ненужный бросок

и должно быть

public void copyImage(Image image) {
    if (image != null) {
        // don't change the width/height of your original image
        int width = image.getWidth(null);
        // int height = image.getWidth(null);
        int height = image.getHeight(null); // *** Note change ***

        // BufferedImage bi = (BufferedImage) image;  // *** no need ***
        Graphics g = getGraphics();

        g.drawImage(image, 0, 0, width, height, null);
        g.dispose();  // save resources
    }
}   

Тестовый код с использованием MCVE с подтверждением концепции:

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

public class TestImage {
    public static final String SOMME_PATH = "https://upload.wikimedia.org/"
            + "wikipedia/commons/thumb/f/fa/Cheshire_Regiment_trench_Somme_1916.jpg"
            + "/1024px-Cheshire_Regiment_trench_Somme_1916.jpg";
    public static final String BATTLE_PATH = "https://upload.wikimedia.org/wikipedia/"
            + "commons/1/13/K%C3%A4mpfe_auf_dem_Doberdo.JPG";

    public static void main(String[] args) {
        int imgW = 1000;
        int imgH = 700;
        MyImage myImage = new MyImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB);
        BufferedImage sommeTrench = null;
        BufferedImage battleOfDoberdò = null;

        try {
            URL url = new URL(SOMME_PATH);
            sommeTrench = ImageIO.read(url);

            url = new URL(BATTLE_PATH);
            battleOfDoberdò = ImageIO.read(url);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        Icon icon = new ImageIcon(myImage);
        JOptionPane.showMessageDialog(null, icon, "Original MyImage", JOptionPane.PLAIN_MESSAGE);

        myImage.copyImage(sommeTrench);
        icon = new ImageIcon(myImage);
        JOptionPane.showMessageDialog(null, icon, "MyImage with Somme Trench", JOptionPane.PLAIN_MESSAGE);

        myImage.copyImage(battleOfDoberdò);        
        icon = new ImageIcon(myImage);
        JOptionPane.showMessageDialog(null, icon, "MyImage with Battle Of Doberdò", JOptionPane.PLAIN_MESSAGE);

    }
}

class MyImage extends BufferedImage {

    public MyImage(int width, int height, int imageType) {
        super(width, height, imageType);
    }

    public void copyImage(Image image) {
        if (image != null) {
            int width = image.getWidth(null);

            int height = image.getHeight(null); // *** Note change ***

            Graphics g = getGraphics();

            g.drawImage(image, 0, 0, width, height, null);
            g.dispose(); // save resources
        }
    }    
}

Если вы запустите этот код, вы увидите 3 изображения, отображаемые как ImageIcons в 3 JOptionPanes, сначала оригинальный пустой объект MyImage, а затем после того, как 2 изображения из Первой мировой войны были скопированы в исходное изображение.

...