11

私の質問:リソース イメージの明るさを変更し、その 3 つのインスタンスを ImageIcons として保持できるようにしたいと考えています。1 つは 50% の明るさ (非常に暗い)、もう 1 つは 75% の明るさ (少し明るい)、最後は 100% の明るさ (元の画像と同じ) です。透明感も残したい。

私が試したこと:私は周りを検索しましたが、最良の解決策は を使用しているように見えますがRescaleOp、それを理解することはできません. scaleFactor と offset が何であるかわかりません。これが私が試したコードです。

public void initialize(String imageLocation, float regularBrightness, float focusedBrightness, float pressedBrightness, String borderTitle) throws IOException {
  BufferedImage bufferedImage = ImageIO.read(ButtonIcon.class.getResource(imageLocation));
  setRegularIcon(getAlteredImageIcon(bufferedImage, regularBrightness));
  setFocusedIcon(getAlteredImageIcon(bufferedImage, focusedBrightness));
  setPressedIcon(getAlteredImageIcon(bufferedImage, pressedBrightness));
  setTitle(borderTitle);
  init();
}

private ImageIcon getAlteredImageIcon(BufferedImage bufferedImage, float brightness) {
  RescaleOp rescaleOp = new RescaleOp(brightness, 0, null);
  return new ImageIcon(rescaleOp.filter(bufferedImage, null));
}

呼び出しは次のようになります。

seeATemplateButton.initialize("/resources/templateIcon-regular.png", 100f, 75f, 50f, "See A Template");
//I think my 100f, 75f, 50f variables need to change, but whenever I change them it behaves unexpectedly (changes colors and stuff).

そのコードで何が起こるか:画像は「見えない」ように見えます。マウスクリックイベントが発生したJLabel上にあり、正常に機能するため、そこにあることがわかります。明るさの変更部分をスキップして、問題なく動作すると言うsetRegularIcon(new ImageIcon(Button.class.getResource(imageLocation));と、明らかに暗くはなりません。

私が必要だと思うもの:offsetscaleFactor、およびfilterメソッドの意味/動作、およびその結果、輝度変数に与える数値を理解するのに役立つものがあります。

どんな助けでも大歓迎です!ありがとう!

4

4 に答える 4

5

ドキュメントは次のように述べています。

再スケーリング操作の擬似コードは次のとおりです。

for each pixel from Source object {
    for each band/component of the pixel {
        dstElement = (srcElement*scaleFactor) + offset
    }
}

これは、すべてのピクセルに対する単なる線形変換です。その変換のパラメータはscaleFactoroffsetです。100% の明るさが必要な場合、この変換は恒等式、つまりdstElement = srcElement. 設定scaleFactor = 1offset = 0てトリックを行います。

ここで、あなたが言うように、75% の明るさで画像を暗くしたいとします。これは、ピクセル値に 0.75 を掛けることになります。欲しいもの: dstElement = 0.75 * srcElement. したがって、scaleFactor =0.75を設定するとoffset = 0うまくいくはずです。値の問題は、値が 0 から 100 になることです。0 から 1 の間の値を使用する必要があります。

于 2012-10-19T19:13:21.920 に答える
4

半透明の黒で画像を上書きすることをお勧めします。

画像に直接書き込みたい場合:

Graphics g = img.getGraphics();
float percentage = .5f; // 50% bright - change this (or set dynamically) as you feel fit
int brightness = (int)(256 - 256 * percentage);
g.setColor(new Color(0,0,0,brightness));
g.fillRect(0, 0, img.getWidth(), img.getHeight());

または、表示目的で画像を使用している場合は、paintComponentメソッドでそれを行います。SSCCE は次のとおりです。

import java.awt.*;
import java.awt.image.*;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;


public class ImageBrightener extends JPanel{

    BufferedImage img;
    float percentage = 0.5f;

    public Dimension getPreferredSize(){
        return new Dimension(img.getWidth(), img.getHeight());
    }

    public ImageBrightener(){
        try {
            img = ImageIO.read(new URL("http://media.giantbomb.com/uploads/0/1176/230441-thehoff_super.jpeg"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(img, 0, 0, this);
        int brightness = (int)(256 - 256 * percentage);
        g.setColor(new Color(0,0,0,brightness));
        g.fillRect(0, 0, getWidth(), getHeight());
    }

    public static void main(String[] args){
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new ImageBrightener());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

編集

上記と同じコードを想定すると、ラスタライザーをいじることでアルファ以外のすべてを操作できます。shadedImage以下に例を示します (この例を使用する場合の代わりにペイントimgします)。これは、256 より大きく 0 より小さい RGB 値のエッジ ケースをキャッチしないことに注意してください。

        img = ImageIO.read(new URL("http://media.giantbomb.com/uploads/0/1176/230441-thehoff_super.jpeg"));
        shadedImage = new BufferedImage(img.getWidth(), img.getWidth(), BufferedImage.TYPE_INT_ARGB);
        shadedImage.getGraphics().drawImage(img, 0, 0, this);

        WritableRaster wr = shadedImage.getRaster();
        int[] pixel = new int[4];

        for(int i = 0; i < wr.getWidth(); i++){
            for(int j = 0; j < wr.getHeight(); j++){
                wr.getPixel(i, j, pixel);
                pixel[0] = (int) (pixel[0] * percentage);
                pixel[1] = (int) (pixel[1] * percentage);
                pixel[2] = (int) (pixel[2] * percentage);
                wr.setPixel(i, j, pixel);
            }
        }
于 2012-10-19T20:42:55.367 に答える
1

研究のためのいくつかの例:

  • AlphaTestオフセットなしで、画像のアルファ透明度のみを 0 から 1 の間で再スケーリングします。偶然にも、画像を 4 分の 3 のサイズにリサンプリングします。

  • RescaleOpTest固定スケールとオフセットなしを使用して同じことを行います。

  • RescaleTest画像のすべてのバンドをオフセットなしで 0 から 2 の間でスケーリングします。

APIに記載されているように、スケールとオフセットは、それぞれ線形関数の勾配とy切片として各バンドに適用されます。

dstElement = (srcElement*scaleFactor) + offset
于 2012-10-20T01:51:49.043 に答える