Konwersja koloru z Hex do Dec z uwzględnieniem alpha

0

Witam!
Ładuję plik jpg, następnie pobieram wszystkie jego pixele do tablicy intów. Potem użytkownik wprowadza wartość szukanego koloru np. : fff6f3fa, w drugim polu tekstowym użytkownik podaje wartość HEX koloru na jaki chce zmienić ten podstawowy czyli (fff6f3fa). Kolory są w zapisie ARGB. Problem tkwi w tym, jeżeli użytkownik podaje kolory z kanałem alpha, to wywala ten błąd:

 
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "fff6f3fa"
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Integer.parseInt(Integer.java:495)
	at okno.jButton3ActionPerformed(okno.java:220)
	at okno.access$200(okno.java:32)
	at okno$3.actionPerformed(okno.java:94)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
	at java.awt.Component.processMouseEvent(Component.java:6505)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
	at java.awt.Component.processEvent(Component.java:6270)
	at java.awt.Container.processEvent(Container.java:2229)
	at java.awt.Component.dispatchEventImpl(Component.java:4861)
	at java.awt.Container.dispatchEventImpl(Container.java:2287)
	at java.awt.Component.dispatchEvent(Component.java:4687)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
	at java.awt.Container.dispatchEventImpl(Container.java:2273)
	at java.awt.Window.dispatchEventImpl(Window.java:2719)
	at java.awt.Component.dispatchEvent(Component.java:4687)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:723)
	at java.awt.EventQueue.access$200(EventQueue.java:103)
	at java.awt.EventQueue$3.run(EventQueue.java:682)
	at java.awt.EventQueue$3.run(EventQueue.java:680)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.awt.EventQueue$4.run(EventQueue.java:696)
	at java.awt.EventQueue$4.run(EventQueue.java:694)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:693)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)

A to kawałek kodu :

 String _base = jTextField2.getText();
        String _target = jTextField3.getText();
        int count = 0;
        int base = Integer.parseInt(_base, 16);
        int target = Integer.parseInt(_target, 16);
        for (int i = 0; i < this.data.length; i++) {
            if (this.data[i] == base) {
                this.data[i] = target;
                count++;
            }
        }
        JOptionPane.showMessageDialog(rootPane, "Wykonano " + count + " zamian");

Jeżeli podam kolory bez alpha czyli f6f3fa wszystko się wykonuje, lecz nie ma żadnych zmian, bo obrazek jest ARGB czyli nic nie znajduję.
Z góry dzięki za pomoc!

0

Przekraczasz zakres int-a. Dziel String wejściowy i wyjściowy na cztery odcinki po dwa znaki i działaj na składowych alfa, r, g i b.
Największa dopuszczalna wartość int-a, to 7fffffff.

0

No faktycznie przekraczam, dzięki ;). Jednak kiedy przeglądam wartości zmiennej w której mam kolor pixela (BufferedImage.getRGB(int x, int y)) to jest w niej też kanał alpha
Przykładowo dla pixela (1,1) wartośc koloru w DEC: -11514540 HEX: ff504d54. To w jaki sposób zapisać liczbę ujemną w HEX? ;)

1

Ty chcesz żeby użytkownik programu wpisywał liczbę ujemną w HEX-ie? To nie jest user-friendly. Możesz skorzystać z klasy JColorChooser user image,
możesz pytać o wartość każdej składowej, możesz pytać o kolor (w HEX-ie) i osobno o wartość alfa z przedziału 0-255.

0

Dzięki, za wszystko. Program się wykonuje, jednak jego wyniki są dziwne.
Tak ładuję jpg(jak coś robię nie tak, to proszę o zwrócenie uwagi):

File f = new File(path.getText());
        // d3d1d6
        if (!path.equals("")) {
            try {
                Image img = ImageIO.read(f);
                img = new ImageIcon(img).getImage();
                this.bf = new BufferedImage(img.getWidth(null),img.getHeight(null),BufferedImage.TYPE_INT_ARGB);
                Graphics g = this.bf.createGraphics();
                g.drawImage(img, 0, 0, null);
                //g.dispose();
                int[] wh = new int[this.bf.getWidth()*this.bf.getHeight()];
               this.bf.getRGB(0, 0, this.bf.getWidth(), this.bf.getHeight(),wh,0,this.bf.getWidth());
               this.data = wh;
               
                info.setText("Załadowany plik: " + plik.getName());
            } catch (IOException ex) {
                Logger.getLogger(okno.class.getName()).log(Level.SEVERE, null, ex);
            }
            
        } else {
            JOptionPane.showMessageDialog(rootPane, "Nie wybrano pliku", "Wybierz plik!", JOptionPane.WARNING_MESSAGE);
        }

Plik się ładuje, nic z nim nie robię, a potem zapisuję. Teoretycznie nic nie powinno się zmienić, na zdjęciu.
Tak zapisuję:

this.bf.setRGB(0, 0, this.bf.getWidth(), this.bf.getHeight(), this.data,0, this.bf.getWidth());
        File fff = new File(this.plik.getAbsolutePath()+"_");
        try {
            ImageIO.write(this.bf, "jpg", fff );
        } catch (IOException ex) {
            Logger.getLogger(okno.class.getName()).log(Level.SEVERE, null, ex);
        }

JPG przed wykonaniem : Bez nazwy.jpg
JPG po wykonaniu(program nic z nim nie robi): Bez nazwsy.jpg

1

Jak to "program nic z nim nie robi"? Oczywiście, że robi. Skąd wiesz w jakim planie graficznym jest obrazek źródłowy po konwersji przez Javę? Tworząc BufferedImage narzucasz mu nowy plan graficzny z palca. A on wcale nie musi być z nim zgodny (i nie jest). Jeżeli obrazek jest np. w RGBA, a ty mu narzucasz ARGB, to kanał alfa zostanie potraktowany jako jeden z kolorów i odwrotnie.

0

Źle się wyraziłem, w kodzie nic robiłem celowo z obrazkiem :P. Masz rację obrazek jest RGBA, a nie ARGB ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1