Как я могу отобразить растровое изображение в апплете Java?

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

<code>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);
    }
}
</code>

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

Ответы на вопрос(6)

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);
    }
}

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

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 файла.

Java Документы:

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

Решение Вопроса

работать при запуске апплета с сервера. Используйте конструктор ImageIcon (URL location) и Пусть 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")

вероятно, это хорошая идея, чтобы правильно избежать \ as \\.

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

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

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

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

 schnaader25 июн. 2009 г., 20:00
Что приводит нас ко второму уроку: проверьте, был ли процесс init (открытие файла) успешным.
 Beska25 июн. 2009 г., 21:59
Как это не ответ? Он упоминает две потенциальные проблемы (плохой escape-символ и возможный недопустимый тип изображения) и способы их устранения.
 OscarRyz25 июн. 2009 г., 21:44
-1, это не ответ, а комментарий. Следует зайти в раздел комментариев. Bit.ly / MohSi
 Eric Petroelje25 июн. 2009 г., 19:56
+ 1 это, наверное, проблема. Единственная причина, по которой вы не получаете ошибку компилятора, заключается в том, что "\ t" является допустимой escape-последовательностью для символа табуляции.
 Michael Myers♦25 июн. 2009 г., 19:56
Я думаю, что у нас есть победитель. Если бы он назвал свой файл "imagetest.bmp", было бы очевидно, в чем проблема.

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

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

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

Я никогда не пробовал

 akarnokd25 июн. 2009 г., 22:04
BMP не поддерживается в Swing / ImageIcon. ImageIO, тем не менее, с удовольствием его читает (ссылка: Forums.sun.com / thread.jspa? ThreadId = 666189)

Ваш ответ на вопрос