Как я могу отобразить растровое изображение в апплете Java? - PullRequest
2 голосов
/ 25 июня 2009

Мне трудно понять, как показать изображение (или ImageIcon) в апплете Java. Ниже мой код. Изображение (test.bmp) существует и находится на диске D, но когда я запускаю его, я получаю окно апплета, в котором ничего нет. Может кто-нибудь сказать мне, что мне не хватает, чтобы заставить ImageIcon показывать?

public class Form1 extends JApplet {
    ImageIcon i;

    public void init(){
        i = new ImageIcon("D:\test.bmp");
    }

    public void paint(Graphics g){
        i.paintIcon(this, g, 0, 0);
    }
}

Спасибо, Стив.

Ответы [ 6 ]

7 голосов
/ 25 июня 2009

Ссылка на изображение через абсолютный локальный путь к файлу может не работать при запуске апплета с сервера. Используйте конструктор ImageIcon (расположение URL) и Пусть URL-адрес указывает на ресурс изображения на сервере. Используйте JApplet.getCodeBase (), чтобы определить, откуда ваш апплет, и добавить к нему имя файла.

public class Form1 extends JApplet {
    Image i;

    public void init() {
        try {
            i = ImageIO.read(new URL(getCodeBase(), "test.bmp"));
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void paint(Graphics g) {
        g.drawImage(i, 0, 0, null);
    }
}

Редактировать: ImageIO поддерживает BMP, и измененный образец работает для меня.

Редактировать 2: Если изображение по-прежнему не отображается, попробуйте "../test.bmp", потому что, когда вы запускаете апплет из, скажем, Eclipse, в нем есть каталог bin кодовая.

Редактировать 3: Если вы поместите свой test.bmp в jar или в путь к классам, вы можете загрузить его тем же способом, но заменив

new URL(getCodeBase(), "test.bmp")

с

Form1.class.getResource("test.bmp")
5 голосов
/ 25 июня 2009

Начнем с того, что, вероятно, хорошей идеей будет правильно выбрать \ as \\.

Отредактировано, чтобы добавить: Вы, вероятно, хотите выучить эквивалент вашего языка (или библиотеки) Path.combine (или File.join), который является методом для получения списка частей пути к файлу и объединения их с подходящим для платформы путем разделитель. Или вы можете написать это самостоятельно на Java, так как разделитель пути задокументирован в File.pathSeparator .

(от макушки головы я не знал, что косая черта всегда работает в ImageIcon, но обратите внимание на другой ответ, который указывает на это).

Кроме того, убедитесь, что вы загружаете файлы поддерживаемого типа, например .png, .gif или .jpg. BMP может поддерживаться в JDK 1.5

Кроме того, если вы работаете в контексте апплета, у вас может не быть доступа к рассматриваемому пути из-за правил песочницы. В этом случае сделайте его доступным по тому же пути, что и к файлу HTML, на котором размещен апплет (возможно, по пути Jar, если мне не изменяет память), и используйте относительный путь.

1 голос
/ 26 июня 2009

ImageJ - это приложение / библиотека с открытым исходным кодом, которое поддерживает майские форматы, включая BMP.

Вот реальный код с использованием BMPDecoder из ImageJ:

Вот лицензионное заявление .

import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.MemoryImageSource;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class BMPDecoder {
    InputStream is;
    int curPos = 0;

    int bitmapOffset; // starting position of image data

    int width; // image width in pixels
    int height; // image height in pixels
    short bitsPerPixel; // 1, 4, 8, or 24 (no color map)
    int compression; // 0 (none), 1 (8-bit RLE), or 2 (4-bit RLE)
    int actualSizeOfBitmap;
    int scanLineSize;
    int actualColorsUsed;

    byte r[], g[], b[]; // color palette
    int noOfEntries;

    byte[] byteData; // Unpacked data
    int[] intData; // Unpacked data
    boolean topDown;

    private int readInt() throws IOException {
        int b1 = is.read();
        int b2 = is.read();
        int b3 = is.read();
        int b4 = is.read();
        curPos += 4;
        return ((b4 << 24) + (b3 << 16) + (b2 << 8) + (b1 << 0));
    }

    private short readShort() throws IOException {
        int b1 = is.read();
        int b2 = is.read();
        curPos += 2;
        return (short) ((b2 << 8) + b1);
    }

    void getFileHeader() throws IOException, Exception {
        // Actual contents (14 bytes):
        short fileType = 0x4d42;// always "BM"
        int fileSize; // size of file in bytes
        short reserved1 = 0; // always 0
        short reserved2 = 0; // always 0

        fileType = readShort();
        if (fileType != 0x4d42)
            throw new Exception("Not a BMP file"); // wrong file type
        fileSize = readInt();
        reserved1 = readShort();
        reserved2 = readShort();
        bitmapOffset = readInt();
    }

    void getBitmapHeader() throws IOException {

        // Actual contents (40 bytes):
        int size; // size of this header in bytes
        short planes; // no. of color planes: always 1
        int sizeOfBitmap; // size of bitmap in bytes (may be 0: if so,
                            // calculate)
        int horzResolution; // horizontal resolution, pixels/meter (may be 0)
        int vertResolution; // vertical resolution, pixels/meter (may be 0)
        int colorsUsed; // no. of colors in palette (if 0, calculate)
        int colorsImportant; // no. of important colors (appear first in
                                // palette) (0 means all are important)
        int noOfPixels;

        size = readInt();
        width = readInt();
        height = readInt();
        planes = readShort();
        bitsPerPixel = readShort();
        compression = readInt();
        sizeOfBitmap = readInt();
        horzResolution = readInt();
        vertResolution = readInt();
        colorsUsed = readInt();
        colorsImportant = readInt();

        topDown = (height < 0);
        if (topDown)
            height = -height;
        noOfPixels = width * height;

        // Scan line is padded with zeroes to be a multiple of four bytes
        scanLineSize = ((width * bitsPerPixel + 31) / 32) * 4;

        actualSizeOfBitmap = scanLineSize * height;

        if (colorsUsed != 0)
            actualColorsUsed = colorsUsed;
        else
        // a value of 0 means we determine this based on the bits per pixel
        if (bitsPerPixel < 16)
            actualColorsUsed = 1 << bitsPerPixel;
        else
            actualColorsUsed = 0; // no palette
    }

    void getPalette() throws IOException {
        noOfEntries = actualColorsUsed;
        // IJ.write("noOfEntries: " + noOfEntries);
        if (noOfEntries > 0) {
            r = new byte[noOfEntries];
            g = new byte[noOfEntries];
            b = new byte[noOfEntries];

            int reserved;
            for (int i = 0; i < noOfEntries; i++) {
                b[i] = (byte) is.read();
                g[i] = (byte) is.read();
                r[i] = (byte) is.read();
                reserved = is.read();
                curPos += 4;
            }
        }
    }

    void unpack(byte[] rawData, int rawOffset, int bpp, byte[] byteData,
            int byteOffset, int w) throws Exception {
        int j = byteOffset;
        int k = rawOffset;
        byte mask;
        int pixPerByte;

        switch (bpp) {
        case 1:
            mask = (byte) 0x01;
            pixPerByte = 8;
            break;
        case 4:
            mask = (byte) 0x0f;
            pixPerByte = 2;
            break;
        case 8:
            mask = (byte) 0xff;
            pixPerByte = 1;
            break;
        default:
            throw new Exception("Unsupported bits-per-pixel value: " + bpp);
        }

        for (int i = 0;;) {
            int shift = 8 - bpp;
            for (int ii = 0; ii < pixPerByte; ii++) {
                byte br = rawData[k];
                br >>= shift;
                byteData[j] = (byte) (br & mask);
                // System.out.println("Setting byteData[" + j + "]=" +
                // Test.byteToHex(byteData[j]));
                j++;
                i++;
                if (i == w)
                    return;
                shift -= bpp;
            }
            k++;
        }
    }

    void unpack24(byte[] rawData, int rawOffset, int[] intData, int intOffset,
            int w) {
        int j = intOffset;
        int k = rawOffset;
        int mask = 0xff;
        for (int i = 0; i < w; i++) {
            int b0 = (((int) (rawData[k++])) & mask);
            int b1 = (((int) (rawData[k++])) & mask) << 8;
            int b2 = (((int) (rawData[k++])) & mask) << 16;
            intData[j] = 0xff000000 | b0 | b1 | b2;
            j++;
        }
    }

    void unpack32(byte[] rawData, int rawOffset, int[] intData, int intOffset,
            int w) {
        int j = intOffset;
        int k = rawOffset;
        int mask = 0xff;
        for (int i = 0; i < w; i++) {
            int b0 = (((int) (rawData[k++])) & mask);
            int b1 = (((int) (rawData[k++])) & mask) << 8;
            int b2 = (((int) (rawData[k++])) & mask) << 16;
            int b3 = (((int) (rawData[k++])) & mask) << 24; // this gets
                                                            // ignored!
            intData[j] = 0xff000000 | b0 | b1 | b2;
            j++;
        }
    }

    void getPixelData() throws IOException, Exception {
        byte[] rawData; // the raw unpacked data

        // Skip to the start of the bitmap data (if we are not already there)
        long skip = bitmapOffset - curPos;
        if (skip > 0) {
            is.skip(skip);
            curPos += skip;
        }

        int len = scanLineSize;
        if (bitsPerPixel > 8)
            intData = new int[width * height];
        else
            byteData = new byte[width * height];
        rawData = new byte[actualSizeOfBitmap];
        int rawOffset = 0;
        int offset = (height - 1) * width;
        for (int i = height - 1; i >= 0; i--) {
            int n = is.read(rawData, rawOffset, len);
            if (n < len)
                throw new Exception("Scan line ended prematurely after " + n
                        + " bytes");
            if (bitsPerPixel == 24)
                unpack24(rawData, rawOffset, intData, offset, width);
            else if (bitsPerPixel == 32)
                unpack32(rawData, rawOffset, intData, offset, width);
            else
                // 8-bits or less
                unpack(rawData, rawOffset, bitsPerPixel, byteData, offset,
                        width);
            rawOffset += len;
            offset -= width;
        }
    }

    public void read(InputStream is) throws IOException, Exception {
        this.is = is;
        getFileHeader();
        getBitmapHeader();
        if (compression != 0)
            throw new Exception("Compression not supported");
        getPalette();
        getPixelData();
    }

    public MemoryImageSource makeImageSource() {
        ColorModel cm;
        MemoryImageSource mis;

        if (noOfEntries > 0) {
            // There is a color palette; create an IndexColorModel
            cm = new IndexColorModel(bitsPerPixel, noOfEntries, r, g, b);
        } else {
            // There is no palette; use the default RGB color model
            cm = ColorModel.getRGBdefault();
        }

        // Create MemoryImageSource

        if (bitsPerPixel > 8) {
            // use one int per pixel
            mis = new MemoryImageSource(width, height, cm, intData, 0, width);
        } else {
            // use one byte per pixel
            mis = new MemoryImageSource(width, height, cm, byteData, 0, width);
        }

        return mis; // this can be used by Component.createImage()
    }

    public static void main(String[] aqgs) {
        BMPDecoder bd = new BMPDecoder();
        try {
            bd.read(BMPDecoder.class.getResourceAsStream("bmp.bmp"));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        JFrame jf = new JFrame();
        JLabel jl = new JLabel();
        ImageIcon ii = new ImageIcon( jl.createImage(bd.makeImageSource()));
        jl.setIcon(ii);
        jf.add(jl);
        jf.pack();
        jf.setVisible(true);
    }
}
1 голос
/ 25 июня 2009

Вместо создания ImageIcon, которому говорят рисовать себя на графике, попробуйте это так:

public class Form1 extends JApplet {
    Image i;

    public void init(){
        i = getImage("D:\\test.bmp");
    }

    public void paint(Graphics g){
        g.drawImage(i,0,0,this);
    }
}

Кроме того, вы можете попробовать использовать .png вместо .bmp файла.

0 голосов
/ 25 июня 2009

BMP-файлы не поддерживаются в Java.

Возможно, вам следует рассмотреть возможность использования других форматов, таких как .png, .gif или .jpg

Если вы действительно ИМЕЕТЕ , чтобы сделать это, вот статья из Java World, которая объясняет, как прочитать файл битовой карты и интерпретировать его.

Java Совет 43: Как читать 8- и 24-битные растровые изображения Microsoft Windows в приложениях Java из JavaWorld

Я никогда не пробовал, хотя

0 голосов
/ 25 июня 2009

Из Java Docs :

При указании пути используйте Интернет-стандартная косая черта ("/") в качестве разделителя

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...