Glüh effekt um Image

Titanpharao

Bekanntes Mitglied
Hallo liebe Community,

habe auch mal wieder eine Frage. Kennt jemand eine möglichkeit ein "glow" effekt um ein Bild zu zeichnen? Aber nicht um ein "eckiges" bild, sondern um eine sprite. Möchte meinen NPC's einen effekt geben, bei einer bestimmten sache. Oder einen einfachen Kontur effekt. Suche schon, vielleicht hat auch jemand sowas schon gemacht.
Vielen danke für ideen.

p.s.: Will halt zeigen ob der NPC ein Quest für dich hat, ohne das dumm "!" wie mans aus den meisten Spielen kennt.
 

Marco13

Top Contributor
Wenn das zur Laufzeit aus einem Bild erstellt werden soll, das um den Sprite herum transparent ist, könnte man das Bild mit einem Gaußfilter weichzeichnen und heller machen, und über das Ergebnisbild dann nochmal das Originalbild drüberpinseln...
Java:
import javax.swing.*;
import javax.imageio.*;
import java.awt.image.*;
import java.awt.*;
import java.io.*;

class ImageGlow
{
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    new ImageGlow();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }


    public ImageGlow() throws Exception
    {
        JFrame f = new JFrame();


        f.getContentPane().setLayout(new GridLayout(1,2));

        BufferedImage input = ImageIO.read(new File("bild1.png"));
        f.getContentPane().add(new JLabel(new ImageIcon(input)));

        BufferedImage output = crateGlow(input);
        f.getContentPane().add(new JLabel(new ImageIcon(output)));


        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);

    }

    private static BufferedImage crateGlow(BufferedImage in)
    {
        int glowSize = 30;

        int iw = in.getWidth();
        int ih = in.getHeight();
        BufferedImage input = new BufferedImage(iw+glowSize*2, ih+glowSize*2, BufferedImage.TYPE_INT_ARGB);
        Graphics g = input.createGraphics();
        g.setColor(new Color(0,0,0,0));
        g.fillRect(0,0,input.getWidth(), input.getHeight());
        g.drawImage(in, glowSize, glowSize, null);
        g.dispose();

        BufferedImage output = new BufferedImage(iw+glowSize*2, ih+glowSize*2, BufferedImage.TYPE_INT_ARGB);
        Kernel kernel = createKernel(glowSize);

        BufferedImageOp op = new ConvolveOp(kernel, ConvolveOp.EDGE_ZERO_FILL, null );
        output = op.filter(input, output);

        RescaleOp rescale = new RescaleOp(10, 0, null);
        output = rescale.filter(output, output);

        g = output.createGraphics();
        g.drawImage(input, 0, 0, null);
        g.dispose();
        return output;
    }

    private static float[] to1D(float a[][])
    {
        float result[] = new float[a.length*a[0].length];
        int index = 0;
        for (int i=0; i<a.length; i++)
        {
            for (int j=0; j<a[i].length; j++)
            {
                result[index] = a[i][j];
                index++;
            }
        }
        return result;
    }

    private static Kernel createKernel(int radius)
    {
        float g[][] = createGaussianKernel(radius, 3.0f, 1.0f);
        float h[] = to1D(g);
        return new Kernel(radius*2+1, radius*2+1, h);
    }

    private static float[][] createGaussianKernel(int arrayRadius, float kernelRadius, float sigma)
    {
        int size = arrayRadius*2+1;
        float sum = 0;
        float result[][] = new float[size][size];
        for (int x=-arrayRadius; x<=arrayRadius; x++)
        {
            for (int y=-arrayRadius; y<=arrayRadius; y++)
            {
                float fx = kernelRadius * (float)x/arrayRadius;
                float fy = kernelRadius * (float)y/arrayRadius;
                int ix = x+arrayRadius;
                int iy = y+arrayRadius;
                float value = gaussian(fx, fy, sigma);
                result[ix][iy] = value;
                sum += value;
            }
        }
        float invSum = 1.0f / sum;
        for (int x=0; x<size; x++)
        {
            for (int y=0; y<size; y++)
            {
                result[x][y] *= invSum;
            }
        }
        return result;
    }


    private static float gaussian(float x, float y, float sigma)
    {
        float nominator = x*x + y*y;
        float sigmaSquared = sigma * sigma;
        float denominator = 2 * sigmaSquared;
        float exponent = -nominator / denominator;
        float power = (float)Math.exp(exponent);
        float factor = 1.0f / (2 * (float)Math.PI * sigmaSquared);
        float result = factor * power;
        return result;
    }
}
 

Titanpharao

Bekanntes Mitglied
Hey danke sieht echt cool aus, nur wieso wird jetzt das transparent in dem neuen Bild so "vergraut"? :/ Brauche nur den Gelben schimmer. Achso und wieso ist das so "gelb"? geht nicht auch blau ;)?
 

Marco13

Top Contributor
Das gepostete war nur ein Test-Hack (um selbst zu sehen, ob das funktioniert und wie es aussieht :oops: ). Da gibt's natürlich etliche Parameter und Stellschrauben und Verbesserungsmöglichkeiten... Das "vergrauen" kommt wohl durch die Transparenz, das müßte man wohl auch irgendwie rausfiltern können (genaugenommen war das "skalieren" nur, um das ausgrauen nicht so stark erscheinen zu lassen). Die Farbe des Glows sollte von der (Rand-) Farbe des Sprites abhängen. Alles andere ... müßte man per Hand noch tunen...
 

Titanpharao

Bekanntes Mitglied
Also die Farbe ist immer Gelb, egal welches Bild ich benutze. Puh ... sieht auch stark unterschiedlich aus von Bild zu Bild. Fummel mal bissel an dem Code rum, sieht aber recht kompliziert aus :D
 

Marco13

Top Contributor
Ohja, das gelb kommt daher, dass das mit dem rescale etwas... grell war... Hier nochmal, etwas vereinfacht und kommentiert.

Das Erstellen des Kernels braucht man eigentlich nicht nachzuvollziehen. Aber ich glaube, um "bessere" Glow-Effekte hinzukriegen, müßte man evtl. die einzelnen Bänder (also speziell den Alpha-Kanal getrennt) betrachten, das könnte dann etwas aufwändiger werden. Dann wäre es vermutlich DOCH einfacher, das ganze als Bild mit PaintShop zu malen ;)

Java:
import javax.swing.*;
import javax.imageio.*;
import java.awt.image.*;
import java.awt.*;
import java.io.*;
import java.util.*;

class ImageGlow
{
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    new ImageGlow();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }


    public ImageGlow() throws Exception
    {
        JFrame f = new JFrame();


        f.getContentPane().setLayout(new GridLayout(1,0));

        BufferedImage input = ImageIO.read(new File("image03.png"));
        JLabel label = new JLabel(new ImageIcon(input));
        label.setBackground(Color.WHITE);
        label.setOpaque(true);
        f.getContentPane().add(label);

        BufferedImage output = crateGlow(input);

        label = new JLabel(new ImageIcon(output));
        label.setBackground(Color.WHITE);
        label.setOpaque(true);
        f.getContentPane().add(label);

        label = new JLabel(new ImageIcon(output));
        label.setBackground(Color.GRAY);
        label.setOpaque(true);
        f.getContentPane().add(label);

        label = new JLabel(new ImageIcon(output));
        label.setBackground(Color.BLACK);
        label.setOpaque(true);
        f.getContentPane().add(label);


        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);

    }

    private static BufferedImage crateGlow(BufferedImage in)
    {
        int glowSize = 30;

        // Eingabebild in die Mitte von einem ARGB-Bild malen, das
        // einen Rand für das Glühen hat
        int iw = in.getWidth();
        int ih = in.getHeight();
        int ow = iw+glowSize*2;
        int oh = iw+glowSize*2;
        BufferedImage input = new BufferedImage(ow, oh, BufferedImage.TYPE_INT_ARGB);
        Graphics g = input.createGraphics();
        g.setColor(new Color(0,0,0,0));
        g.fillRect(0,0,input.getWidth(), input.getHeight());
        g.drawImage(in, glowSize, glowSize, null);
        g.dispose();

        // Kernel erstellen, der das bild weichzeichnet
        int gg = glowSize * glowSize;
        float matrix[] = new float[gg];
        Arrays.fill(matrix, 1.0f/gg);
        //Kernel kernel = new Kernel(glowSize, glowSize, matrix);
        Kernel kernel = createKernel(glowSize); //new Kernel(glowSize, glowSize, matrix);
        BufferedImageOp op = new ConvolveOp(kernel, ConvolveOp.EDGE_ZERO_FILL, null );

        // Weichzeichnen
        BufferedImage output = new BufferedImage(ow, oh, BufferedImage.TYPE_INT_ARGB);
        output = op.filter(input, output);

        // Das Glühen heller machen
        RescaleOp rescale = new RescaleOp(
            new float[]{2.0f,2.0f,2.0f,2.0f},
            new float[]{0,0,0,0}, null);
        output = rescale.filter(output, output);

        // Originalbild drübermalen
        g = output.createGraphics();
        g.drawImage(input, 0, 0, null);
        g.dispose();
        return output;
    }


    private static Kernel createKernel(int arrayRadius)
    {
        float kernelRadius = 3;
        float sigma = 1;
        int size = arrayRadius*2+1;
        float sum = 0;
        float result[] = new float[size*size];
        for (int x=-arrayRadius; x<=arrayRadius; x++)
        {
            for (int y=-arrayRadius; y<=arrayRadius; y++)
            {
                float fx = kernelRadius * (float)x/arrayRadius;
                float fy = kernelRadius * (float)y/arrayRadius;
                int ix = x+arrayRadius;
                int iy = y+arrayRadius;
                float value = gaussian(fx, fy, sigma);
                result[ix+iy*size] = value;
                sum += value;
            }
        }
        float invSum = 1.0f / sum;
        for (int x=0; x<size*size; x++)
        {
            result[x] *= invSum;
        }
        return new Kernel(size, size, result);
    }


    private static float gaussian(float x, float y, float sigma)
    {
        float nominator = x*x + y*y;
        float sigmaSquared = sigma * sigma;
        float denominator = 2 * sigmaSquared;
        float exponent = -nominator / denominator;
        float power = (float)Math.exp(exponent);
        float factor = 1.0f / (2 * (float)Math.PI * sigmaSquared);
        float result = factor * power;
        return result;
    }

}
 

Titanpharao

Bekanntes Mitglied
So, wenn man mit JAVA nicht mehr weiter weis, bedient man sich halt anderen Mitteln. Habs jetzt über ein Photoshop Skript gemacht. Also wenn ich mal etwas ändern will, dauert es genauso lange wie im Quellcode :).
Wenigstens etwas programmiert bei der Sache :D

Trotzdem vielen Dank für deine mühe und diese wirren JAVA Klassen.
 

Marco13

Top Contributor
Naja. Alles, was man mit Photoshop machen kann, kann man auch mit Java machen.

Dieses Programm generiert urheberrechtlich geschützte Bilder, Bilder mit strafrechtlich relevantem Inhalt, Bilder auf denen zu sehen ist, wie das Wetter in 14 Jahren sein wird, ein Bild von einer Katze die einen Cheezburger ißt, und auch Bilder von deinen Sprites mit dem perfektesten Glüh-Effekt, den du dir vorstellen kannst. Einfach die auskommentierte Zeile einkommentieren und starten, dann werden alle diese Bilder auf die Festplatte geschrieben. Das könnte eine Weile dauern, aber... das ist es ja wohl wert :D

Java:
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;

class ImageMaker
{
    public static void main(String args[])
    {
        BufferedImage image =
            new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
        while (nextImage(image, 0));
    }

    private static boolean nextImage(BufferedImage image, int i)
    {
        int x = i % image.getWidth();
        int y = i / image.getWidth();
        if (i>=image.getWidth()*image.getHeight())
        {
            return false;
        }
        int rgb = image.getRGB(x,y);
        if (rgb < Integer.MAX_VALUE)
        {
            rgb++;
            image.setRGB(x, y, rgb);
            //store(image);
            return true;
        }
        rgb = -Integer.MAX_VALUE;
        image.setRGB(x, y, rgb);
        return nextImage(image, i+1);
    }

    private static long counter = 0;
    private static void store(BufferedImage image)
    {
        String name = "image"+System.nanoTime()+"-"+counter+".png";
        counter++;
        try
        {
            ImageIO.write(image, "png", new File(name));
        }
        catch (Exception e)
        {
        }
    }
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T LWJGL 2.9.2: Seltsamer Effekt beim Rendern (VertexShader Problem?) Spiele- und Multimedia-Programmierung 3
S JME - Licht hat keinen Effekt Spiele- und Multimedia-Programmierung 2
radiac Java Screen Blur Effekt Spiele- und Multimedia-Programmierung 12
B Glow Effekt Spiele- und Multimedia-Programmierung 2
Quaxli komischer Effekt bei g.drawPolygon Spiele- und Multimedia-Programmierung 11
J OpenGL (JOGL) - Radial Blur Effekt (Glow) Spiele- und Multimedia-Programmierung 2
D Zwei Fragen (Exponential Fog und Schein-nach-außen-Effekt) Spiele- und Multimedia-Programmierung 6
L Schnee Effekt in 2D Spiel Spiele- und Multimedia-Programmierung 15
L Regen Effekt in 2D Spiel Spiele- und Multimedia-Programmierung 21
T Position eines Image verändern mithilfe eines Timers Spiele- und Multimedia-Programmierung 6
K Video: Per Image Information Spiele- und Multimedia-Programmierung 3
M Image unpainten Spiele- und Multimedia-Programmierung 3
B Bild ohne Image auf die Festplatte streamen Spiele- und Multimedia-Programmierung 4
X Android Slick AE Image Pfad Spiele- und Multimedia-Programmierung 3
A Drehen von einem Image Spiele- und Multimedia-Programmierung 4
C Mouseover Area genau wie Image Spiele- und Multimedia-Programmierung 8
L Slick-Image aus byte-array erzeugen Spiele- und Multimedia-Programmierung 2
0 2D Spiel Welt scrollen bzw Image erweitern Spiele- und Multimedia-Programmierung 2
T jME3: awt.Image <-> jME3.Image Spiele- und Multimedia-Programmierung 7
F nur Ausschnitt eines Image zeichnen Spiele- und Multimedia-Programmierung 9
F Hintergrund bei Image entfernen Spiele- und Multimedia-Programmierung 4
S Image-Einbindung Spiele- und Multimedia-Programmierung 5
StrikeTom .gif animation als image abspielen Spiele- und Multimedia-Programmierung 2
radiac Aktuelles ScreenBild als Image? Spiele- und Multimedia-Programmierung 6
Stillmatic1985 Buffered Image drucken Spiele- und Multimedia-Programmierung 1
P Culling von Image-Objekten Spiele- und Multimedia-Programmierung 3
E Alternative zu import com.sun.image.codec.jpeg.JPEGCodec ? Spiele- und Multimedia-Programmierung 1
E JPCT background image Spiele- und Multimedia-Programmierung 3
P Grosses Bufferd Image Drucken Print API Spiele- und Multimedia-Programmierung 3
G Image drucken Spiele- und Multimedia-Programmierung 17
S Image will nicht laden Spiele- und Multimedia-Programmierung 3
A Image in BufferedImage konvertieren Spiele- und Multimedia-Programmierung 2
O Image dynamisch erstellen. Spiele- und Multimedia-Programmierung 6
G Punkt in Image auf Transparenz prüfen Spiele- und Multimedia-Programmierung 6
G Bereich im Image löschen Spiele- und Multimedia-Programmierung 4
H image.setRGB() zeichnet falsch Spiele- und Multimedia-Programmierung 3
R Transparente Farbe von (Buffered) Image Spiele- und Multimedia-Programmierung 10
D Welcher Image Typ am besten für 2D-Spiele geeignet? Spiele- und Multimedia-Programmierung 5
O Image konvertieren in monochrom scharz/weiß Spiele- und Multimedia-Programmierung 3
F Image eines bestimmten Bereichs eines JPanels erstellen Spiele- und Multimedia-Programmierung 4
T Spiel als Vollbild starten mit Image als HIntergrund Spiele- und Multimedia-Programmierung 8
O transparente farbe in Image mit Graphics Spiele- und Multimedia-Programmierung 8
S Image to BufferedImage Spiele- und Multimedia-Programmierung 3
D Image.getGraphics() in einem Frame Spiele- und Multimedia-Programmierung 4

Ähnliche Java Themen

Neue Themen


Oben