Program na modifikaci obrázků – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Program na modifikaci obrázků – Java – Fórum – Programujte.comProgram na modifikaci obrázků – Java – Fórum – Programujte.com

 

kremlas0
Duch
3. 2. 2016   #1
-
0
-

Ahoj, potřeboval bych poradit s jedním projektem do školy. Jedná se o program na zpracování a úpravu obrázků a přestože v mnoha ohledech funguje tak, jak má, vždy, když se rozhodnu programovat, narazím na nějakej totální renonc.

První problém je spíš teoretický - mám funkci load, která načte obrázek a následně jej má zobrazit. Na každém stroji se to ale chová jinak - buď obrázek vůbec nezobrazí, nebo jej zobrazí po minimalizaci a obnovení okna. Následně buď zamrzne na původním načteném obrázku, nebo zobrazuje všechny úpravy. Vím, že je tam nejspíš problém s verzí javy, nicméně dá-li se tomu nějakým způsobem vyhnout a udělat program v tomhle ohledu konzistentní, byl bych vděčný za každou radu.

Druhý problém mám s rotací obrázku. Zde přikládám kód:

  private void jMenuItem7ActionPerformed(java.awt.event.ActionEvent evt) {                                           
        int w = twitchPic.getWidth();
        int h = twitchPic.getHeight();

        BufferedImage rotate = new BufferedImage(h, w, BufferedImage.TYPE_INT_RGB);
        AffineTransform at = AffineTransform.getRotateInstance(Math.PI/2, w / 2, h / 2);
        Graphics2D g = (Graphics2D) rotate.createGraphics();
        g.drawImage(twitchPic, at, null);
        g.dispose();
        twitchPic = rotate;
        actions.add("CW");
    }

Tato funkce totiž obrázek nejen orotuje, ale zároveň jej ořízne. Chyba by tedy měla být v rozměrech orotovaného obrázku, nicméně ty vypadají správně.

Připojen obrázek.

Připojen obrázek.

Připojen obrázek.

Dále pracuji na barevných módech pro obrázek - normální a greyscale. Převádím to na HSV a upravuji saturaci. Kód:

    private void jMenuItem9ActionPerformed(java.awt.event.ActionEvent evt) {                                           
        if(actions.contains("normal")){
            System.err.println("this picture is already in normal mode");
        }
        for(int i=0; i<twitchPic.getWidth(); i++) {
            for(int j=0; j<twitchPic.getHeight(); j++) {
                int r = new Color(twitchPic.getRGB(i, j)).getRed();
                int g = new Color(twitchPic.getRGB(i, j)).getGreen();
                int b = new Color(twitchPic.getRGB(i, j)).getBlue();
                float[] hsv = new float[3];
                Color.RGBtoHSB(r,g,b,hsv);
                hsv[1] = (float) 1.0;
                twitchPic.setRGB(i,j,Color.HSBtoRGB(hsv[0],hsv[1],hsv[2]));
            }
        }
        for(int k=0; k<actions.size()-1;k++){
            if(actions.get(k).equals("greyscale")){
                actions.remove(k);
            }
        }
        actions.add("normal");
    }

U greyscale mám v HSV[1] hodnotu 0.0 a pracuje to v pořádku. Když ale dám v normálním módu do HSV[1] hodnotu 1.1, získám místo normální saturace prakticky červený filtr. Čím je to způsobeno? Hue a Value by měly být stejné (pokud jsem nic nepřehlédl) a saturace přeci operuje jen s tmavostí barvy...

Mám taky funkci na reset všech úprav na daném obrázku tím, že jej znova načtu:

    private void jMenuItem11ActionPerformed(java.awt.event.ActionEvent evt) {                                            
        Graphics gr = openedPic.getGraphics();
        paint(gr);
        twitchPic = openedPic;
        actions.clear();
        deleted = null;
    }

problém je, že to udělá tento pro mne totálně nepochopitelný glitch:

Připojen obrázek.

Poslední ještě nemám naimplementovaný, ale chtěl bych přidat filtry např. na rozmazání nebo zaostření

public static final float[] SHARPEN = { 
        0.f, -1.f,  0.f,
       -1.f,  5.f, -1.f,
        0.f, -1.f,  0.f
    };

I přes teoretickou znalost ale nemůžu přijít na to, jak správně zapsat patřičný for cyklus, který by takový filtr na jednotlivé pixely aplikoval.

Já vím, je toho hodně, ale za každou pomoc bych byl opravdu neskonale vděčný.

Nahlásit jako SPAM
IP: 2a00:1028:8b40:a99e:cd71:...–
kremlas0
Duch
4. 2. 2016   #2
-
0
-

#1 kremlas
Update: rotaci už jsem vyřešil, greyscale v podstatě taky. Jen jsem při tom narazil na další problém:

for(int i=0; i<twitchPic.getWidth(); i++) {
            for(int j=0; j<twitchPic.getHeight(); j++) {
                double r = new Color(twitchPic.getRGB(i, j)).getRed();
                double g = new Color(twitchPic.getRGB(i, j)).getGreen();
                double b = new Color(twitchPic.getRGB(i, j)).getBlue();
                //double max = Math.max(Math.max(r,g),b);
                if((r>g)&&(r>b)){  
                    
                        g=g+0.99*(r-g);
                        b=b+0.99*(r-b);
                    
                }
                if((g>r)&&(g>b)){  
                    //if((r<(g-10))&&(b<(g-10))){
                        r=r+0.99*(g-r);
                        b=b+0.99*(g-b);
                    //}
                }
                if((b>g)&&(b>r)){  
                    //if((g<(b-10))&&(r<(b-10))){
                        g=g+0.99*(b-g);
                        r=r+0.99*(b-r);
                    //}
                }
                float[] hsv = new float[3];
                Color.RGBtoHSB((int)r,(int)g,(int)b,hsv);
                twitchPic.setRGB(i,j,Color.HSBtoRGB(hsv[0],hsv[1],hsv[2]));
            }
        }

Z nějakého důvodu nemůžu použít 32 bitový zápis barvy a musím dělat převod z RGB do HSV a zpět. Hlavně ale ztrácím data barvy kvůli převodu na int (stejné u bitového zápisu). Při aplikaci inverzní funkce získám obrázek s odlišnou barvou pixelů. Potřebuji tedy nejspíš RGB informace o pixelech uložit do pole.

Řekněme, že budu mít pole RGB[3], kde RGB[0]=r, RGB[1]=g a RGB[2]=b. Mám tedy barvu pro jeden pixel.

Jak by mělo vypadat pole pixels typu RGB[3]? Jak z něj mohu zpět získat informace?

Zkoušel jsem pixels[][][] = new double[pic.getWidth()][pic.getHeight()][RGB.length], ale při snaze do něj zapisovat a zpět z něj číst ztrácím veškeré info o barvě.

Nahlásit jako SPAM
IP: 83.208.42.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 1 host

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý