Täytyy jälleen kysäistä täältä, kun ei millään meinaa itse keksiä.
Onko mahdollista tallentaa isosta kuvasta vain osan toiseen Image-tyypin muuttujaan? Isosta kuvasta voi toki piirtää pienen osan näytölle drawImage()-metodilla, mutta kun tämä pitäisi tallentaa omaan Image-muuttujaan, niin siitä ei sitten tulekaan mitään.
Jos viimeinen lause pääsi hämäämään: Miten tallennan Image-tyypin oliosta vain osan toiseen samanlaiseen olioon.
Puhutaanhan nyt java.awt.Imagesta?
Imagella on getGraphics()-metodi, joka palauttaa Graphics-olion, joka piirtää siihen Imageen, ei siis ruudulle.
Luo siis uusi tyhjä Image, ota sen Graphics ja piirrä tuota Graphicsia käyttäen haluamasi osa isosta kuvasta tähän vastaluotuun.
Kiitokset pikaisesta vastauksesta.
Olin käsittänyt tuon Image- ja Graphics-olion suhteen hieman väärin. Enköhän tuolla saa homman toimimaan.
Yritin napata Graphics -oliota pieneltä kuvalta ja piirtää siihen, mutta eihän tuo suostu tottelemaan. Kääntäjä antaa virheen yrittäessäni pyytää pieneltä kuvalta Graphics- otusta. Mitä teen väärin tai jätän tekemättä?
Metodi, jota käytän näyttää tältä:
public void piirraIsostaPieneen(){ Image pieni, iso; //ladataan pieneen kuvaan varulta jotain URL url = this.getClass().getResource("temp.png"); pieni=Toolkit.getDefaultToolkit().getImage(url); url = this.getClass().getResource("iso.png"); iso=Toolkit.getDefaultToolkit().getImage(url); pieni.getGraphics().drawImage(iso, 0, 0, 100, 100, 50, 50, 100, 100, this); }
Tällaista virhettä pukkaa:
java.lang.UnsupportedOperationException: getGraphics() not valid for images created with createImage(producer) at sun.awt.image.ToolkitImage.getGraphics(Unknown Source)
Toolkitin getImagella ladatut kuvat on näköjään ei-off-screen (on-screen?) -kuvia, joihin ei voi piirtää.
No, java.awt.Componentilla on createImage(int w, int h), joka ainakin tekee tuollaisia piirtämiseen sopivia (tyhjiä) kuvia.
Kiitoksia jälleen avusta.
Vieläkään en silti saa koodia toimimaan. Nyt tosin virhe on toinen, joten kaipa tässä edistytään. Ohjelma heittää NullPointteria yrittäessäni pyytää createImage():lla luodun kuvan Graphics-oliota. Eli jostain syystä tuo olio on null.
Component c=null; Image img, iso; URL url = this.getClass().getResource("iso.png"); iso=Toolkit.getDefaultToolkit().getImage(url); img=c.createImage(100, 100); //NullPointerException tulee tästä img.getGraphics().drawImage(iso, 0, 0, 100, 100, 0, 0, 100, 100, this);
Niin, c on null kun sen itse asetat nulliksi tuolla ylempänä :)
Tuo java.awt.Component on kaikkien AWT- ja Swing-komponenttien kantaluokka, joten jos tuo sun piirraIsostaPieneen()-metodi sattuis olemaan vaikka Appletissa, voisit sanoa ihan suoraan this.createImage(...)
Blaze kirjoitti:
Niin, c on null kun sen itse asetat nulliksi tuolla ylempänä :)
Niinpä tietysti. Miten tuo Component pitäisi määritellä vai meneekö kovinkin hankalaksi?
Metodi on JPanelin perillisessä, josta siis myös löytyy tuo createImage(). No yritimpä nyt näin, mutta nullPointterilta ei vältytä tuon Graphics -olion kanssa. Tämänhän pitäisi toimia, mutta en millään keksi mistä jää kiinni.
Jos laitan koodin Applettiin, se toimii moitteetta. Voisi olettaa, että myös JPanelin perillisessä pelittäisi.
Image temp=this.createImage(100, 100); //this viitaa siis JPaneliin System.out.println(temp.getGraphics());
No, jos tuota huomenna yrittelisi uusilla silmillä. Kiitokset avusta!
int x = 255; int y = 32; int leveys = 110; int korkeus = 50; try { // Luodaan kuvaolio, mihin haluttu osa piirretään. BufferedImage kohde = new BufferedImage(leveys, korkeus, BufferedImage.TYPE_INT_RGB); // Luetaan kuvatiedosto, tavalla ei juurikaan ole väliä. // Haetaan kuitenkin mallin vuoksi ohjelmointiputkan logo ImageIO:lla. Image lahde = ImageIO.read(new URL("https://www.ohjelmointiputka.net/img/palkki2.jpg")); // Piirretään haluttu osa noudetusta kuvasta tuohon pari riviä // ylempänä luotuun kuvaan. kohde.getGraphics().drawImage(lahde, 0, 0, leveys, korkeus, x, y, x+leveys, y+korkeus, null); // Ja sitten mitä ikinä haluaakaan tehdä sillä kuvalla... // Kirjoitellaan se vaikka System.outiin kun ei muutakaan keksitä. :D ImageIO.write(kohde, "PNG", System.out); } catch (MalformedURLException e) { System.out.println("Huono urli"); } catch (IOException e) { System.out.println("Kuvan lukemisessa on jotain häikkää"); }
Kiitoksia!
Nyt sain kuvaan piirtämisen toimimaan. Nyt kuitenkin yrittäessäni saada ison kuvan pinkin taustan häivytettyä läpinäkyväksi alkaa ongelmia taas ilmetä. Käytän seuraavaa luokkaa - joka on toiminut hyvin muissa projekteissa pelkkien Image-instanssien kanssa - kuvan värin häivyttämiseen. Luokan käsittelyn jälkeen kuva on kokonaan musta.
public class SetTranspatency { public static Image makeTransparent(Image srcImage){ ImageFilter RGBFilter=new RGBImageFilter(){ Color pink=new Color(0xFFFF00FF); //100% transparent public int triggerColor1=pink.getRGB() | 0xFF000000; public final int filterRGB(int x, int y, int rgb){ if((rgb | 0xFF000000)==triggerColor1){ return 0x00FFFFFF & rgb; //returns transparent white } else{ return rgb; //rest of the colors are returned unchanced } } }; ImageProducer imgProducer=new FilteredImageSource(srcImage.getSource(), RGBFilter); return Toolkit.getDefaultToolkit().createImage(imgProducer); } }
Kuitenkin käyttäessäni seuraavaa luokkaa, kuva näkyy oikein(pinkki häivytetynä).
public class SetTranspatency { public static Image makeTransparent(Image srcImage){ Color toChange=new Color(0xFFFF00FF); //100% transparent int w = srcImage.getWidth(null); int h = srcImage.getHeight(null); BufferedImage dst = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = dst.createGraphics(); g2.drawImage(srcImage, 0, 0, null); g2.dispose(); int repl = toChange.getRGB(); int xp = new Color(0, 0, 0, 0).getRGB(); System.out.printf("repl = %d xp = %d%n", repl, xp); int count = 0; for(int y = 0; y < h; y++) { for(int x = 0; x < w; x++) { if(dst.getRGB(x, y) == repl) { count++; dst.setRGB(x, y, xp); } } } System.out.println("count = " + count); return dst; } }
Jompaa kumpaa luokkaa käyttäen poistan tavallisesta Image:sta pinkin värin ja sen jälkeen luon kuvasta BufferedImagen näin:
... iso=SetTranspatency.makeTransparent(iso); bImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); bImage.getGraphics().drawImage(iso, 0, 0, 100, 100, this); ...
Mistä johtuu ensimmäisen luokan palauttama virheellinen kuva? Eipä tässä sinällään hätää ole kun kerran jälkimmäisellä tavalla toimii, ihmettelin vain miksei ensimmäinen luokka toimisi myös.
Aihe on jo aika vanha, joten et voi enää vastata siihen.