1

Тема: 2D графіка в Java. Зміна кольору завантаженого зображення

Є одне зображення, і його потрібно намалювати на панелі(JPanel) декілька раз в різних кольорах (+ воно повинне бути частково прозорим). І тут починається... відкриваємо саме зображення, створюємо новий Image, попіксельно перемальовуємо картинку в потрібному кольорі (з потрібним значення альфи), ну і тоді вже й показуємо на екрані.

От щоб перемалювати картинку потрібно надто багато часу, а хотілося ще й з цього зробити . Як це діло пришвидшити, і чи взагалі краще тут про Swing забути?

2

Re: 2D графіка в Java. Зміна кольору завантаженого зображення

Якщо ви з альфоканалом не робите анімацію, то спробуйте зробити перетворення зображення до його відображення, а потім намалюйте готовий результат.

3

Re: 2D графіка в Java. Зміна кольору завантаженого зображення

0xDADA11C7 написав:

Якщо ви з альфоканалом не робите анімацію, то спробуйте зробити перетворення зображення до його відображення, а потім намалюйте готовий результат.

Анімацію не спішу робити, коли один кадр перефарбовує 2 секунди діла не буде( Знайшла класс PixelGrabber, може так швидше буде працювати.

4

Re: 2D графіка в Java. Зміна кольору завантаженого зображення

Викладіть код, так легше буде вам допомогти.

5

Re: 2D графіка в Java. Зміна кольору завантаженого зображення

0xDADA11C7 написав:

Викладіть код, так легше буде вам допомогти.

Прихований текст

public class Animation extends Thread
{
    private final int UNCLOUDED = -16777216;
    private final int NET = -1;
   
    private BufferedImage Img, StartImg;
    private DrawComponent Layer;
    private Color color;
    private int X, Y, Width, Height;
   
    public Animation(
                        int x,
                        int y,
                        Color color,
                        DrawComponent layer,
                        BufferedImage startImg
                    )
    {
        this.X = x;
        this.Y = y;
        this.color = color;
        this.Layer = layer;
        this.StartImg = startImg;
        Img  = new BufferedImage(
                                    startImg.getWidth(null),
                                    startImg.getHeight(null),
                                    BufferedImage.TYPE_4BYTE_ABGR
                                );
        start();
    }
   
    @Override
    public void run()
    {
        int w = Img.getWidth(null),
            h = Img.getHeight(null);
        int i, j;
        Color c;
        Graphics g = Img.getGraphics();
        int red = color.getRed(),
            green = color.getGreen(),
            blue = color.getBlue();
        int rgb = color.getRGB();   
        //перемальовуємо StartImg в потрібному кольорі на Img
        for (i = 0; i<h; i++)
        {
            for (j = 0; j<w; j++)
            {
                rgb = StartImg.getRGB(i, j);
                if (rgb == UNCLOUDED) continue;//повністю прозорий піксель
                if (rgb == NET) c = color;        //повністю не прозорий піксель
                else
                {
                    c = new Color(red, green, blue, 255+(rgb+1)/0x10000);
                }
                g.setColor(c);
                g.fillRect(i, j, 1, 1);
            }
        }
        Layer.paindImg(X, Y, Width, Height, Img);
        System.out.print("111");
    }
   
}

6

Re: 2D графіка в Java. Зміна кольору завантаженого зображення

Уже зробила. Ніби працєш добре.

Прихований текст

public class DrawCanvas extends Component{
   
    private Image Img;

    public DrawCanvas(){}
   
    public void drawFrame(int x, int y, int width, int height, int[] pixels)
    {
        //Створюємо зображення з масиву пікселей
        Img = createImage(new MemoryImageSource(width, height, pixels, 0, width));
        repaint();
        setBounds(x, y, width+x, height+y);
    }
   
    @Override
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
        super.paint(g);
        g.drawImage(Img, 0, 0, this);
    }
}

public class Animation extends Thread
{   
    private int X, Y, Width, Height, RGB;
    private int[] Pixels;
    private DrawCanvas Canvas;
   
    public Animation(int x, int y, int width, int height, int[] pixels, DrawCanvas canvas)
    {
        this.X = x;
        this.Y = y;
        this.Width = width;
        this.Height = height;
        this.Pixels = pixels;
        this.Canvas = canvas;
    }
   
    public Animation(int x, int y, Image img, DrawCanvas canvas)
    {
        this.X = x;
        this.Y = y;
        this.Width = img.getWidth(null);
        this.Height = img.getHeight(null);
       
        //Перетворюємо зображення в масив пікселів
        Pixels = new int[ img.getWidth(null)*img.getHeight(null)];
        PixelGrabber gr = new PixelGrabber(    img,
                                            0,
                                            0,
                                            img.getWidth(null),
                                            img.getHeight(null),
                                            Pixels,
                                            0,
                                            img.getWidth(null));
        try {
            gr.grabPixels();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       
        this.Canvas = canvas;
        RGB = -1;
    }
   
    public void setColor(Color color)
    {
        this.RGB = color.getRGB();
    }
   
    public void setColor(int red, int green, int blue)
    {
        RGB = 255-blue + (255-green)*0x100 + (255-red)*0x10000;
        RGB = (-1)*RGB - 1;
    }
   
    @Override
    public synchronized void start() {
        // TODO Auto-generated method stub
        super.start();
    }
   
    //Перемальовуємо кадр
    private void repaintFrame()
    {
        int j;
        for (j = 0; j < Pixels.length; j++)
            Pixels[j] = RGB - (255-Pixels[j]%0x100)*0x1000000;
    }
   
    //Виводимо  кадр на екран
    private void playFrame()
    {
        Canvas.drawFrame(X, Y, Width, Height, Pixels);
    }
       
    @Override
    public void run() {
        // TODO Auto-generated method stub
        long t1 = System.nanoTime();
        repaintFrame();
        playFrame();
        System.out.print(System.nanoTime()-t1);
    }
}

Подякували: 0xDADA11C71

7

Re: 2D графіка в Java. Зміна кольору завантаженого зображення

Написала програмку яку хтіла. Нарешті руки до неї знову долізли)

Прихований текст
public class Main {

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

}

public class MainFrame extends JFrame{

/**
     * 
     */
    private static final long serialVersionUID = 1L;
private JPanel P;
    
    public MainFrame()
    {
        Dimension dimension = new Dimension(500, 500);
        setPreferredSize(dimension);
        setMaximumSize(dimension);
        setMinimumSize(dimension);
        setTitle("Сніговик");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        
        P = new JPanel();
        P.setPreferredSize(dimension);
        P.setMaximumSize(dimension);
        P.setMinimumSize(dimension);
        add(P);    
        
        mypaint();
        lisener();
    }
    
    private void mypaint(){
        try
        {
            P.setLayout(null);
            
            Comp c = new Comp();
            
            P.add(c);
        }catch( Exception e){
            
        }    
    }

    
    private void lisener(){
        P.addMouseListener(new MouseListener() {
            
            @Override
            public void mouseReleased(MouseEvent e) {
                // TODO Auto-generated method stub
                
            }
            
            @Override
            public void mousePressed(MouseEvent e) {
                // TODO Auto-generated method stub
                if (e.getModifiers()==e.BUTTON1_MASK){
                    Comp c = new Comp();
                    P.add(c);
                    int x = e.getX();
                    int y = e.getY();
                    int r, g, b;
                    r = (255*x)/500;
                    g = (255*y)/500;
                    b = (255*(x+y))/1000;
                    
                    c.animation(new Color(r, g, b), x, y);
                }
            }
            
            @Override
            public void mouseExited(MouseEvent e) {
                // TODO Auto-generated method stub
                
            }
            
            @Override
            public void mouseEntered(MouseEvent e) {
                // TODO Auto-generated method stub
                
            }
            
            @Override
            public void mouseClicked(MouseEvent e) {
                // TODO Auto-generated method stub
                
            }
        });
    }
    
}

public class Comp extends Component{

    private int X, Y, Width, Height;
    private Image Img;
    
    public Comp(){
    }
    
    public void setLocation(int x, int y){
        this.X = x;
        this.Y = y;
        super.setBounds(this.X, this.Y, this.Width, this.Height);
    }
    
    public synchronized void setImage(Image img){
        this.Img = img;
    }
    
    public void setSizeComponent(int width, int height){
        this.Width = width;
        this.Height = height;
        super.setBounds(this.X, this.Y, this.Width, this.Height);
    }
    
    public void paint(Graphics g){
        super.paint(g);
        g.drawImage(Img, 0, 0, null);
        //g.fillRect(0, 0, Width, Height);
    }
    
    public void animation(Color color, int x, int y){
        Animation a = new Animation(this);
        a.setLocation(x, y);
        a.setColor(color);
        a.start();
    }
    
}

public class Animation extends Thread {

    private ArrayList<String> Frames;
    private Comp Element;
    private int ImgWidth, ImgHeight;
    private Color color;
        
    public Animation(Comp element) {
        this.Element = element;
        Frames = new ArrayList<>();
        
        //Кадри анімації
        Frames.add(new String("1.jpg"));
        Frames.add(new String("2.jpg"));
        Frames.add(new String("3.jpg"));
        Frames.add(new String("4.jpg"));
    }
    
    public void run(){    
        int i, n = Frames.size();
        int array[];
        RepaintThred repaint = null;
        Image img;
        for (i=0; i<n; i++){
            array = getPixels(loadImage(Frames.get(i)));
            repaintFrame(array);
            img = createImage(array);
            Element.setSizeComponent(ImgWidth, ImgHeight);
            if ((repaint!=null)&&(repaint.isAlive())){
                try {
                    repaint.join(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                repaint = new RepaintThred(Element, img);
            } else {
                repaint = new RepaintThred(Element, img);
            }
        }
    }
    
    private Image loadImage(String address) {
        try {
            Image img = ImageIO.read(new File(address));
            this.ImgWidth = img.getWidth(null);
            this.ImgHeight = img.getHeight(null);
            return img;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            this.ImgWidth = 0;
            this.ImgHeight = 0;
            return null;
        }
    }
    
    private int[] getPixels(Image img) {
        int pixels[] = new int[this.ImgWidth*this.ImgHeight];
        PixelGrabber gr = new PixelGrabber(    img, 
                                            0, 
                                            0, 
                                            this.ImgWidth, 
                                            this.ImgHeight, 
                                            pixels, 
                                            0, 
                                            this.ImgWidth);
        try {
            gr.grabPixels();
            return pixels;
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }
    
    private Image createImage(int pixels[]) {
        Component comp = new Component() {
                private static final long serialVersionUID = 1L;
        };
        Image img = comp.createImage(new MemoryImageSource (
                                                            this.ImgWidth, 
                                                            this.ImgHeight, 
                                                            pixels, 
                                                            0, 
                                                            this.ImgWidth)
                                                            );
        return img;
    }
    
    public void start(){
        super.start();
    }
    
    // Зміна основного кольору
    private void repaintFrame(int pixels[]) {
        int i, r, g, b;
        Color c = color;
        int Red = c.getRed(), Blue = c.getBlue(), Green = c.getGreen();
        for (i = 0; i < pixels.length; i++) {
            if (pixels[i] == -16777216) {
                pixels[i] = 0x00000000;
                continue;
            }
            pixels[i] = -(pixels[i] + 1);
            r = pixels[i]/0x10000;
            g = pixels[i]/0x100 - r*0x100;
            b = pixels[i] - r*0x10000 - g*0x100;
            r = (Red+r)>255?255:(Red+r);
            g = (Green+g)>255?255:(Green+g);
            b = (Blue+b)>255?255:(Blue+b);
            pixels[i] = -(255-r)*0x10000 - (255-g)*0x100 - (255-b)-1;
        }
    }
    
    public void setLocation(int x, int y){
        loadImage(Frames.get(0));
        Element.setLocation(x-ImgWidth/2, y-ImgHeight/2);
    }
    
    public void setColor(Color color){
        this.color = color;
    }
    
}

public class RepaintThred extends Thread{
    
    private Comp Element;
    
    public RepaintThred(Comp element, Image img) {
        // TODO Auto-generated constructor stub
        this.Element = element;
        element.setImage(img);
        super.start();
    }
    
    public void run(){
        Element.repaint();
        try {
            super.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Ну але тут всього 4 нещасні кадрики((, але й вони мусорять папку з програмою. Можна якось загрузити в javu *.gif і перемалювати у потрібний колір, чи добавити flash-анімацію, і її вже перефарбовувати в програмі?

Подякували: 0xDADA11C71

8 Востаннє редагувалося 0xDADA11C7 (21.08.2014 22:39:41)

Re: 2D графіка в Java. Зміна кольору завантаженого зображення

Запакуйте програму і використані файли в JAR. І викладіть скріншоти/анімовану гіфку/відео роботи вашої програми.

9

Re: 2D графіка в Java. Зміна кольору завантаженого зображення

Програма по клику мишки малює кольорові кружочки. Ну і на цьому все)

https://lh6.googleusercontent.com/hhD0ZnwycUs5YszQ0Ml_xKGEAArvKTFQ0DBJRATY3BzHzQN-h-RHvCty-Wkyh9rb4rB7T1aZIxE=w1280-h580

В архіві *.jar і самі кадри анімації.

Post's attachments

Game_8.rar 14.28 kb, 406 downloads since 2014-08-22 

Подякували: 0xDADA11C71