简体   繁体   English

如何在Java小程序中显示位图图像?

[英]How can I display a bitmap image in a Java applet?

I am having a hard time figuring out how to show an Image (or ImageIcon) in a Java applet. 我很难弄清楚如何在Java applet中显示Image(或ImageIcon)。 The following is my code. 以下是我的代码。 The picture (test.bmp) does exist and is on the D drive but when I run this I get the applet window with nothing in it. 图片(test.bmp)确实存在并且在D驱动器上,但是当我运行它时,我得到的applet窗口中没有任何内容。 Can somebody tell me what I am missing to make the ImageIcon show? 有人可以告诉我我缺少什么来制作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);
    }
}

Thanks, Steve. 谢谢,史蒂夫。

Referencing your image through an absolute local file path might not work when you run your applet from a server. 从服务器运行applet时,通过绝对本地文件路径引用映像可能不起作用。 Use the ImageIcon (URL location) constructor and Have the URL point to the image resource on the server. 使用ImageIcon(URL位置)构造函数并使 URL指向服务器上的图像资源。 Use the JApplet.getCodeBase() to determine where your applet originates and append the file name to it. 使用JApplet.getCodeBase()确定applet的来源,并将文件名附加到其中。

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

Edit: ImageIO supports BMP and the changed sample works for me. 编辑: ImageIO支持BMP,更改的示例适合我。

Edit 2: If it still doesn't display the image, try "../test.bmp" because when you run an applet from lets say Eclipse it has the bin directory as the codebase. 编辑2:如果它仍然没有显示图像,请尝试“../test.bmp”,因为当你运行applet时,我们说它有bin目录作为代码库。

Edit 3: If you put your test.bmp into the jar or on the classpath, you can load it using the same way but replacing 编辑3:如果将test.bmp放入jar或类路径中,可以使用相同的方式加载它,但是替换

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

with

Form1.class.getResource("test.bmp")

To start with, it's probably a good idea to correctly escape your \\ as \\\\. 首先,正确地将\\ _ \\作为\\\\的转义可能是个好主意。

Edited to add: You probably want to learn your language's (or library's) equivalent of Path.combine (or File.join) which is a method for taking a list of file path parts and combining them with the platform-appropriate path separator. 编辑添加:您可能希望学习与Path.combine(或File.join)相当的语言(或库),这是一种获取文件路径部分列表并将它们与适合平台的路径分隔符相结合的方法。 Or you can write it yourself quickly in Java, as the path separator is documented in File.pathSeparator . 或者您可以在Java中快速编写它,因为File.pathSeparator中记录了路径分隔符。

(Off the top of my head, I didn't know that forward slash always works in ImageIcon, but note the other response that indicates this). (在我的脑海中,我不知道正斜杠总是在ImageIcon中工作,但请注意另一个表明这一点的响应)。

Additionally, make sure you are loading a supported file type, such as .png, .gif or .jpg. 此外,请确保您要加载支持的文件类型,例如.png,.gif或.jpg。 BMP may be supported in JDK 1.5 JDK 1.5中可能支持BMP

Also, if you are running in an Applet context, you may not have access to the path in question due to sandboxing rules. 此外,如果您在Applet上下文中运行,则由于沙盒规则,您可能无法访问相关路径。 In that case, make it available in the same path as to the HTML file hosting the applet (possibly in the Jar's path, if memory serves me), and use a relative path. 在这种情况下,使其在与托管applet的HTML文件相同的路径中可用(可能在Jar的路径中,如果内存为我提供),并使用相对路径。

Instead of making an ImageIcon that is told to draw itself onto a graphics, try it this way: 而不是让一个被告知将自己绘制到图形上的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);
    }
}

Also, you may want to try using .png instead of a .bmp file. 此外,您可能想尝试使用.png而不是.bmp文件。

ImageJ is an Open Source application / library that has support for may formats including BMP. ImageJ是一个开源应用程序/库,支持包括BMP在内的may格式。

Here is some real code using BMPDecoder from ImageJ: 以下是使用ImageJ的BMPDecoder的一些实际代码:

Here is the license statement . 这是许可声明

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

From the Java Docs : 来自Java Docs

When specifying a path, use the Internet-standard forward-slash ("/") as a separator 指定路径时,请使用Internet标准正斜杠(“/”)作为分隔符

bmp files are not supprted in java. 在java中不支持bmp文件。

You should probably consider unsing other formats such as .png, .gif or .jpg 您应该考虑使用其他格式,例如.png,.gif或.jpg

If you really HAVE to do it, here's an article from Java World that explains how to read the bit map file and interpret it. 如果你真的做到这一点,这里是从Java世界的文章,介绍了如何读取位图文件,把它解释。

Java Tip 43: How to read 8- and 24-bit Microsoft Windows bitmaps in Java applications from JavaWorld Java技巧43:如何JavaWorld中 读取Java应用程序中的8位和24位Microsoft Windows位图

I've never tried though 我从来没有尝试过

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM