1

すべてJavaで、ファイルをPNGに変換し、プロセスを逆にしたいと思っています。

画像にint-RGB形式を使用し、ファイルのバイトをRGB整数のバイトにします。これにより、画像が生成されます。

これは、バイトを赤色で保存するだけで機能するようになりましたが、緑と青の使用方法もわかりません。

これは私が現在使用しているコードで、赤のみを使用しており、正常に機能します。

public static void fileToImage(String sourceFile, String imageFile) throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream(sourceFile));
    int size = ((int) Math.sqrt(dis.available())) + 2;
    BufferedImage image = new BufferedImage(size,size, BufferedImage.TYPE_INT_RGB);
    for (int y = 0; y < size; y++) {
        for (int x = 0; x < size; x++) {
            int red = dis.read(); // I'm using only red
            int green = 0; // default
            int blue = 0; // default
            int rgb = (0xFF << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);
            image.setRGB(x, y, rgb);
        }
    }
    dis.close();
    ImageIO.write(image, "png", new File(imageFile));
}

public static void imageToFile(String imageFile, String outputFile) throws IOException {
    BufferedImage image = ImageIO.read(new File(imageFile));
    DataOutputStream dos = new DataOutputStream(new FileOutputStream(outputFile));
    for (int y = 0; y < image.getHeight(); y++) {
        for (int x = 0; x < image.getWidth(); x++) {
            int rgb = image.getRGB(x, y);
            int red = (rgb >> 16) & 0xFF;
            int green = (rgb >> 8) & 0xFF;
            int blue = rgb & 0xFF;
            dos.write(red); // I'm using only red
        }
    }
    dos.close();
}

編集:さて、私はコードを変更しました、ここにあります:

public static void fileToImage(String sourceFile, String imageFile) throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream(sourceFile));
    int size = ((int) Math.sqrt(dis.available())) + 2;
    BufferedImage image = new BufferedImage(size,size, BufferedImage.TYPE_INT_RGB);
    for (int y = 0; y < size; y++) {
        for (int x = 0; x < size; x++) {
            int red = dis.read();
            int green = dis.read();
            int blue = dis.read();
            int rgb = (0xFF << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);
            image.setRGB(x, y, rgb);
        }
    }
    dis.close();
    ImageIO.write(image, "png", new File(imageFile));
}

public static void imageToFile(String imageFile, String outputFile) throws IOException {
    BufferedImage image = ImageIO.read(new File(imageFile));
    DataOutputStream dos = new DataOutputStream(new FileOutputStream(outputFile));
    for (int y = 0; y < image.getHeight(); y++) {
        for (int x = 0; x < image.getWidth(); x++) {
            int rgb = image.getRGB(x, y);
            int red = (rgb >> 16) & 0xFF;
            int green = (rgb >> 8) & 0xFF;
            int blue = rgb & 0xFF;
            dos.write(red);
            dos.write(green);
            dos.write(blue);
        }
    }
    dos.close();
}

これは「機能」しますが、期待どおりではありません。画像の「サイズ」が間違っていると思うので、作成されたPNGにはたくさんの黒いスペースがあります。このため、PNGを元のファイルに変換し直すと、元のファイルよりもはるかに大きくなります。

編集:私が今抱えている問題はこれです:たとえば、fileToImageメソッドを使用して次のコンテンツを含むテキストファイルをPNGに変換する場合:hello world!次に、imageToFileを使用して変換し直します。出力は次のとおりです。helloworld!SSSSSSSSSSSSSSS(Sは「スペース」を表し、15個あります)

編集:まだこれを理解することはできません。これが私が使用しているものです:

private static final int NAN = -1;

private static int readByte(DataInputStream dis) throws IOException {
    int b;
    try {
        b = dis.readByte();
    } catch (EOFException e) {
        b = NAN;
    }
    return b;
}

public static void fileToImage(String sourceFile, String imageFile) throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream(sourceFile));
    int size = ((int) Math.sqrt(dis.available())) + 2;
    BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
    for (int y = 0; y < size; y++) {
        boolean finished = false;
        for (int x = 0; x < size; x++) {
            int alpha = 3;
            int red = readByte(dis);
            int green = readByte(dis);
            int blue = readByte(dis);
            if (red == NAN) {
                alpha--;
                red = 0;
            }
            if (green == NAN) {
                alpha--;
                green = 0;
            }
            if (blue == NAN) {
                alpha--;
                blue = 0;
            }
            int rgb = ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);
            image.setRGB(x, y, rgb);
            if (alpha < 3) {
                finished = true;
                break;
            }
        }
        if (finished) break;
    }
    dis.close();
    ImageIO.write(image, "png", new File(imageFile));
}

public static void imageToFile(String imageFile, String outputFile) throws IOException {
    BufferedImage image = ImageIO.read(new File(imageFile));
    DataOutputStream dos = new DataOutputStream(new FileOutputStream(outputFile));
    for (int y = 0; y < image.getHeight(); y++) {
        boolean finished = false;
        for (int x = 0; x < image.getWidth(); x++) {
            int rgb = image.getRGB(x, y);
            int alpha = (rgb >> 24) & 0xFF;
            int red = (rgb >> 16) & 0xFF;
            int green = (rgb >> 8) & 0xFF;
            int blue = rgb & 0xFF;
            if (alpha == 0) {
                finished = true;
                break;
            }
            if (alpha >= 1) dos.write(red);
            if (alpha >= 2) dos.write(green);
            if (alpha == 3) dos.write(blue);
        }
        if (finished) break;
    }
    dos.close();
}
4

2 に答える 2

2

内側のループを少し調整するだけでいいと思います。小さなヘルパー メソッドを使用すると、これが使いやすくなりますが、私のスケッチは少し見にくいと思います。

int myReadByte(DataInputStream dis) {
    int b;
    try {
        b = dis.readByte():
    } catch (EOFException e) {
        b = 0;
    }
    return b;
}

今、このヘルパーで...

for (int x = 0; x < size; x++) {
        int red = myReadByte(dis);
        int green = myReadByte(dis);
        int blue = myReadByte(dis);
        int rgb = (0xFF << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);
        image.setRGB(x, y, rgb);

for (int x = 0; x < image.getWidth(); x++) {
        int rgb = image.getRGB(x, y);
        int red = (rgb >> 16) & 0xFF;
        int green = (rgb >> 8) & 0xFF;
        int blue = rgb & 0xFF;
        dos.write(red);
        dos.write(green);
        dos.write(blue);
    }
于 2012-07-03T23:17:08.853 に答える