Frage

Ich arbeite an Code zum Einfärben eines Bildes in Java.Grundsätzlich möchte ich etwas in der Art des GIMP-Befehls „colorize“ tun, sodass ich, wenn ich ein BufferedImage und eine Farbe habe, das Bild mit der angegebenen Farbe einfärben kann.Hat jemand irgendwelche Ideen?Meine derzeit beste Vermutung, so etwas zu tun, besteht darin, den RGB-Wert jedes Pixels im BufferedImage abzurufen und den RGB-Wert der Farbe mit einem gewissen Skalierungsfaktor hinzuzufügen.

War es hilfreich?

Lösung

Ich habe den Colorize-Befehl von GIMP noch nie verwendet.Wenn Sie jedoch den RGB-Wert jedes Pixels erhalten und ihm einen RGB-Wert hinzufügen, sollten Sie wirklich a verwenden LookupOp. Hier ist ein Code, den ich geschrieben habe, um eine BufferedImageOp auf ein BufferedImage anzuwenden.

Anhand von Nicks Beispiel von oben sehen Sie hier, wie ich es machen würde.

Sei y = 0,3*r + 0,59*g + 0,11*b für jedes Pixel

(R1, G1, B1) ist das, womit Sie sich folben

protected LookupOp createColorizeOp(short R1, short G1, short B1) {
    short[] alpha = new short[256];
    short[] red = new short[256];
    short[] green = new short[256];
    short[] blue = new short[256];

    int Y = 0.3*R + 0.59*G + 0.11*B

    for (short i = 0; i < 256; i++) {
        alpha[i] = i;
        red[i] = (R1 + i*.3)/2;
        green[i] = (G1 + i*.59)/2;
        blue[i] = (B1 + i*.11)/2;
    }

    short[][] data = new short[][] {
            red, green, blue, alpha
    };

    LookupTable lookupTable = new ShortLookupTable(0, data);
    return new LookupOp(lookupTable, null);
}

Es entsteht ein BufferedImageOp Dadurch wird jede Farbe ausgeblendet, wenn der Masken-Boolesche Wert wahr ist.

Es ist auch einfach anzurufen.

BufferedImageOp colorizeFilter = createColorizeOp(R1, G1, B1);
BufferedImage targetImage = colorizeFilter.filter(sourceImage, null);

Wenn dies nicht das ist, wonach Sie suchen, empfehle ich Ihnen, einen genaueren Blick auf BufferedImageOp zu werfen.

Dies wäre auch effizienter, da Sie die Berechnungen nicht mehrmals für verschiedene Bilder durchführen müssten.Oder führen Sie die Berechnungen für verschiedene BufferedImages noch einmal durch, solange sich die Werte R1, G1, B1 nicht ändern.

Andere Tipps

Lassen Y = 0.3*R + 0.59*G + 0.11*B für jedes Pixel im Bild, und stellen Sie sie dann auf ein

((R1+Y)/2,(G1+Y)/2,(B1+Y)/2)

Wenn (R1,G1,B1) ist das, womit Sie kolorieren.

Dies funktioniert genau wie die Colorize-Funktion in GIMP und bewahrt die Transparenz.Ich habe auch ein paar Dinge wie Kontrast und Helligkeit, Farbton, Sat und Leuchtkraft hinzugefügt – 0circle0 Google Me –> „Sprite Creator 3“

import java.awt.Color;
import java.awt.image.BufferedImage;

public class Colorizer
{
    public static final int MAX_COLOR = 256;

    public static final float LUMINANCE_RED = 0.2126f;
    public static final float LUMINANCE_GREEN = 0.7152f;
    public static final float LUMINANCE_BLUE = 0.0722f;

    double hue = 180;
    double saturation = 50;
    double lightness = 0;

    int[] lum_red_lookup;
    int[] lum_green_lookup;
    int[] lum_blue_lookup;

    int[] final_red_lookup;
    int[] final_green_lookup;
    int[] final_blue_lookup;

    public Colorizer()
    {
        doInit();
    }

    public void doHSB(double t_hue, double t_sat, double t_bri, BufferedImage image)
    {
        hue = t_hue;
        saturation = t_sat;
        lightness = t_bri;
        doInit();
        doColorize(image);
    }

    private void doInit()
    {
        lum_red_lookup = new int[MAX_COLOR];
        lum_green_lookup = new int[MAX_COLOR];
        lum_blue_lookup = new int[MAX_COLOR];

        double temp_hue = hue / 360f;
        double temp_sat = saturation / 100f;

        final_red_lookup = new int[MAX_COLOR];
        final_green_lookup = new int[MAX_COLOR];
        final_blue_lookup = new int[MAX_COLOR];

        for (int i = 0; i < MAX_COLOR; ++i)
        {
            lum_red_lookup[i] = (int) (i * LUMINANCE_RED);
            lum_green_lookup[i] = (int) (i * LUMINANCE_GREEN);
            lum_blue_lookup[i] = (int) (i * LUMINANCE_BLUE);

            double temp_light = (double) i / 255f;

            Color color = new Color(Color.HSBtoRGB((float) temp_hue, (float) temp_sat, (float) temp_light));

            final_red_lookup[i] = (int) (color.getRed());
            final_green_lookup[i] = (int) (color.getGreen());
            final_blue_lookup[i] = (int) (color.getBlue());
        }
    }

    public void doColorize(BufferedImage image)
    {
        int height = image.getHeight();
        int width;

        while (height-- != 0)
        {
            width = image.getWidth();

            while (width-- != 0)
            {
                Color color = new Color(image.getRGB(width, height), true);

                int lum = lum_red_lookup[color.getRed()] + lum_green_lookup[color.getGreen()] + lum_blue_lookup[color.getBlue()];

                if (lightness > 0)
                {
                    lum = (int) ((double) lum * (100f - lightness) / 100f);
                    lum += 255f - (100f - lightness) * 255f / 100f;
                }
                else if (lightness < 0)
                {
                    lum = (int) (((double) lum * (lightness + 100f)) / 100f);
                }
                Color final_color = new Color(final_red_lookup[lum], final_green_lookup[lum], final_blue_lookup[lum], color.getAlpha());
                image.setRGB(width, height, final_color.getRGB());
            }
        }
    }

    public BufferedImage changeContrast(BufferedImage inImage, float increasingFactor)
    {
        int w = inImage.getWidth();
        int h = inImage.getHeight();

        BufferedImage outImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        for (int i = 0; i < w; i++)
        {
            for (int j = 0; j < h; j++)
            {
                Color color = new Color(inImage.getRGB(i, j), true);
                int r, g, b, a;
                float fr, fg, fb;

                r = color.getRed();
                fr = (r - 128) * increasingFactor + 128;
                r = (int) fr;
                r = keep256(r);

                g = color.getGreen();
                fg = (g - 128) * increasingFactor + 128;
                g = (int) fg;
                g = keep256(g);

                b = color.getBlue();
                fb = (b - 128) * increasingFactor + 128;
                b = (int) fb;
                b = keep256(b);

                a = color.getAlpha();

                outImage.setRGB(i, j, new Color(r, g, b, a).getRGB());
            }
        }
        return outImage;
    }

    public BufferedImage changeGreen(BufferedImage inImage, int increasingFactor)
    {
        int w = inImage.getWidth();
        int h = inImage.getHeight();

        BufferedImage outImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

        for (int i = 0; i < w; i++)
        {
            for (int j = 0; j < h; j++)
            {
                Color color = new Color(inImage.getRGB(i, j), true);
                int r, g, b, a;
                r = color.getRed();
                g = keep256(color.getGreen() + increasingFactor);
                b = color.getBlue();
                a = color.getAlpha();

                outImage.setRGB(i, j, new Color(r, g, b, a).getRGB());
            }
        }
        return outImage;
    }

    public BufferedImage changeBlue(BufferedImage inImage, int increasingFactor)
    {
        int w = inImage.getWidth();
        int h = inImage.getHeight();

        BufferedImage outImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

        for (int i = 0; i < w; i++)
        {
            for (int j = 0; j < h; j++)
            {
                Color color = new Color(inImage.getRGB(i, j), true);
                int r, g, b, a;
                r = color.getRed();
                g = color.getGreen();
                b = keep256(color.getBlue() + increasingFactor);
                a = color.getAlpha();

                outImage.setRGB(i, j, new Color(r, g, b, a).getRGB());
            }
        }
        return outImage;
    }

    public BufferedImage changeRed(BufferedImage inImage, int increasingFactor)
    {
        int w = inImage.getWidth();
        int h = inImage.getHeight();

        BufferedImage outImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

        for (int i = 0; i < w; i++)
        {
            for (int j = 0; j < h; j++)
            {
                Color color = new Color(inImage.getRGB(i, j), true);
                int r, g, b, a;
                r = keep256(color.getRed() + increasingFactor);
                g = color.getGreen();
                b = color.getBlue();
                a = color.getAlpha();

                outImage.setRGB(i, j, new Color(r, g, b, a).getRGB());
            }
        }
        return outImage;
    }

    public BufferedImage changeBrightness(BufferedImage inImage, int increasingFactor)
    {
        int w = inImage.getWidth();
        int h = inImage.getHeight();

        BufferedImage outImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

        for (int i = 0; i < w; i++)
        {
            for (int j = 0; j < h; j++)
            {
                Color color = new Color(inImage.getRGB(i, j), true);

                int r, g, b, a;

                r = keep256(color.getRed() + increasingFactor);
                g = keep256(color.getGreen() + increasingFactor);
                b = keep256(color.getBlue() + increasingFactor);
                a = color.getAlpha();

                outImage.setRGB(i, j, new Color(r, g, b, a).getRGB());
            }
        }
        return outImage;
    }

    public int keep256(int i)
    {
        if (i <= 255 && i >= 0)
            return i;
        if (i > 255)
            return 255;
        return 0;
    }
}

Ich wollte genau das Gleiche tun, was das Frageposter tun wollte, aber die obige Konvertierung entfernte keine Farben wie GIMP (z. B. Grün mit einer roten Überlagerung ergab eine unangenehme braune Farbe usw.).Also habe ich den Quellcode für GIMP heruntergeladen und den C-Code in Java konvertiert.

Poste es in diesem Thread, nur für den Fall, dass jemand anderes das Gleiche tun möchte (da es der erste Thread ist, der bei Google erscheint).Die Konvertierung ändert immer noch die weiße Farbe, wenn dies nicht der Fall sein sollte. Es handelt sich wahrscheinlich um ein Umwandlungsproblem von double in int.Die Klasse konvertiert ein BufferedImage direkt.

public class Colorize {

public static final int MAX_COLOR = 256;

public static final float LUMINANCE_RED   = 0.2126f;
public static final float LUMINANCE_GREEN = 0.7152f;
public static final float LUMINANCE_BLUE  = 0.0722f;

double hue        = 180;
double saturation =  50;
double lightness  =   0;

int [] lum_red_lookup;
int [] lum_green_lookup;
int [] lum_blue_lookup;

int [] final_red_lookup;
int [] final_green_lookup;
int [] final_blue_lookup;

public Colorize( int red, int green, int blue )
{
   doInit();
}

public Colorize( double t_hue, double t_sat, double t_bri )
{
   hue = t_hue;
   saturation = t_sat;
   lightness = t_bri;
   doInit();
}

public Colorize( double t_hue, double t_sat )
{
   hue = t_hue;
   saturation = t_sat;
   doInit();
}

public Colorize( double t_hue )
{
   hue = t_hue;
   doInit();
}

public Colorize()
{
   doInit();
}

private void doInit()
{
   lum_red_lookup   = new int [MAX_COLOR];
   lum_green_lookup = new int [MAX_COLOR];
   lum_blue_lookup  = new int [MAX_COLOR];

   double temp_hue = hue / 360f;
   double temp_sat = saturation / 100f;

   final_red_lookup   = new int [MAX_COLOR];
   final_green_lookup = new int [MAX_COLOR];
   final_blue_lookup  = new int [MAX_COLOR];

   for( int i = 0; i < MAX_COLOR; ++i )
   {
      lum_red_lookup  [i] = ( int )( i * LUMINANCE_RED );
      lum_green_lookup[i] = ( int )( i * LUMINANCE_GREEN );
      lum_blue_lookup [i] = ( int )( i * LUMINANCE_BLUE );

      double temp_light = (double)i / 255f;

      Color color = new Color( Color.HSBtoRGB( (float)temp_hue, 
                                               (float)temp_sat, 
                                               (float)temp_light ) );

      final_red_lookup  [i] = ( int )( color.getRed() );
      final_green_lookup[i] = ( int )( color.getGreen() );
      final_blue_lookup [i] = ( int )( color.getBlue() );
   }
}

public void doColorize( BufferedImage image )
{
   int height = image.getHeight();
   int width;

   while( height-- != 0 )
   {
      width = image.getWidth();

      while( width-- != 0 )
      {
         Color color = new Color( image.getRGB( width, height ) );

         int lum = lum_red_lookup  [color.getRed  ()] +
                   lum_green_lookup[color.getGreen()] +
                   lum_blue_lookup [color.getBlue ()];

         if( lightness > 0 )
         {
            lum = (int)((double)lum * (100f - lightness) / 100f);
            lum += 255f - (100f - lightness) * 255f / 100f;
         }
         else if( lightness < 0 )
         {
            lum = (int)(((double)lum * lightness + 100f) / 100f);
         }

         Color final_color = new Color( final_red_lookup[lum],
                                        final_green_lookup[lum],
                                        final_blue_lookup[lum],
                                        color.getAlpha() );

         image.setRGB( width, height, final_color.getRGB() );

      }
   }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top