0

XBR4xアルゴリズムでプログラムImageResizerを使用して、古い2Dゲームの.gif画像を32x32から48x48にアップスケールしています。

正確な手順:

  1. プログラムが.gifを開かないため、すべての画像の名前を手動で.jpegに変更します
  2. 画像のサイズを変更すると、プログラムによって.bmpとして保存されます
  3. 画像の名前を手動で.gifに再度変更します。

問題:

ペイントで画像を見ると、非常によく見えます。RGBBufferedImageで描画すると、突然、背景色ではない白/灰色の〜1pxの境界線が表示され、画像が直接隣り合って配置されます。私はそれらの画像のモザイク全体を持っているので、白い境界線はダメです。

画像32x32:ここに画像の説明を入力してください

アップスケーリング後の画像48x48:ここに画像の説明を入力してください

白い境界線のある4つの地球画像のゲーム内スクリーンショット:ここに画像の説明を入力してください

質問:

それらの境界はどのように発生しますか?そして、これに答えることができない場合、低解像度のゲーム画像をアップスケーリングしてピクセル化されていないように見せるためのより信頼性の高い方法はありますか?

4

4 に答える 4

1

これは画像サイズ変更アルゴリズムのアーティファクトだと思います。たとえば、XnViewで見ると、境界線は結合される前にアップスケールされた画像の1つに実際に表示されます。これを修正する最善の方法は、別のツールを使用して画像のサイズを変更することです。これにより、ユーザーはそのような境界線の効果を制御できますが、これを使用する必要がある場合でも、3x3グリッドを作成することで問題を回避できます。元の画像(96x96)、144x144に拡大してから、中央の48x48の部分を切り取ります。これにより、境界線の影響がなくなります。

于 2012-07-30T17:00:08.347 に答える
1

境界線は、前述のツールによって実行されたスケーリング手順の結果です。質問の拡大縮小画像とImage.getScaledInstance()を使用して作成された拡大縮小画像に基づいてタイルを表示するこのデモについて考えてみます。

独自のスケーリング方法を使用する場合は、より最適化されたソリューションについて、The Perils of Image.getScaledInstance()を確認してください。

ここに画像の説明を入力してください

import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class TestImageScale {

    public static void main(String[] args) {
        try {
            BufferedImage original = ImageIO.read(new URL(
                    "http://i.stack.imgur.com/rY2i8.gif"));
            Image scaled = original.getScaledInstance(48, 48,
                    Image.SCALE_AREA_AVERAGING);
            BufferedImage scaledOP = ImageIO.read(new URL(
                    "http://i.stack.imgur.com/Argxi.png"));

            BufferedImage tilesOP = buildTiles(scaledOP, 3, 3);
            BufferedImage tiles = buildTiles(scaled, 3, 3);

            JPanel panel = new JPanel();
            panel.add(new JLabel(new ImageIcon(tilesOP)));
            panel.add(new JLabel(new ImageIcon(tiles)));

            JOptionPane.showMessageDialog(null, panel,
                    "Tiles: OP vs getScaledInstance",
                    JOptionPane.INFORMATION_MESSAGE);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, e.getMessage(), "Failure",
                    JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        }
    }

    static BufferedImage buildTiles(Image tile, int rows, int columns) {

        int width = tile.getWidth(null);
        int height = tile.getHeight(null);

        BufferedImage dest = GraphicsEnvironment
                .getLocalGraphicsEnvironment()
                .getDefaultScreenDevice()
                .getDefaultConfiguration()
                .createCompatibleImage(width * rows, height * columns,
                        Transparency.TRANSLUCENT);
        Graphics g = dest.getGraphics();
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < columns; col++) {
                g.drawImage(tile, row * width, col * width, null);
            }
        }

        g.dispose();

        return dest;
    }
}
于 2012-07-31T03:44:21.083 に答える
0

ただの大げさな推測:元の画像にはアルファチャネルがありますか(またはサイズ変更時に暗黙的にアルファチャネルを作成しますか)?アルファを使用して画像のサイズを変更する場合、スケーリングプロセスでは、画像の外側の領域が透明であると想定され、境界ピクセルも部分的に透明になる場合があります。

于 2012-07-30T17:01:14.700 に答える
0

ツールの開発者であるHawkyntにメールを送信しましたが、エラーはツールではなくMicrosoftの実装にあるようで、彼はそれを修正しました(実際、Multiple Image Resizer .NETのようなさらに大きなツールにも問題があります)。これは彼が彼のプログラムについて言ったことです:

「幅や高さを手動で入力すると、選択したアルゴリズムによって画像のサイズが変更され、すべてがうまくいきました。

その後、Microsoftバージョンのバイキュービックサイズ変更アルゴリズムを実装するGDI+のresampleコマンドを使用しました。この実装には欠陥があるため、300px未満の画像の左側と上部に1つのピクセルが生成されます。

サイズ変更した画像を必要以上に1ピクセル大きくし、左と上に1ピクセルシフトするだけで修正したので、白い境界線が見えなくなり、ターゲット画像のサイズが期待どおりになりました。」

于 2012-08-01T22:39:54.937 に答える