image.java

来自「j2me设计的界面包」· Java 代码 · 共 722 行 · 第 1/2 页

JAVA
722
字号
            // there is no Image.dispose method in existance.
            System.gc();System.gc();
            return new Image(javax.microedition.lcdui.Image.createImage(path));
        }
    }
    
    /**
     * creates an image from an InputStream
     * 
     * @param stream a given InputStream
     * @throws java.io.IOException 
     */
    public static Image createImage(InputStream stream) throws IOException {
        try {
            return new Image(javax.microedition.lcdui.Image.createImage(stream));
        } catch(OutOfMemoryError err) {
            // Images have a major bug on many phones where they sometimes throw 
            // an OOM with no reason. A system.gc followed by the same call over
            // solves the problem. This has something to do with the fact that 
            // there is no Image.dispose method in existance.
            System.gc();System.gc();
            return new Image(javax.microedition.lcdui.Image.createImage(stream));
        }
    }
    
    /**
     * creates an image from an RGB image
     * 
     * @param rgb the RGB image array data
     * @param width the image width
     * @param height the image height
     * @return an image from an RGB image
     */
    public static Image createImage(int[] rgb, int width, int height) {
        try {
            Image i = new Image(javax.microedition.lcdui.Image.createRGBImage(rgb, width, height, true));
            
            // its already set so might as well do the test
            i.testOpaque(rgb);
            return i;
        } catch(OutOfMemoryError err) {
            // Images have a major bug on many phones where they sometimes throw 
            // an OOM with no reason. A system.gc followed by the same call over
            // solves the problem. This has something to do with the fact that 
            // there is no Image.dispose method in existance.
            System.gc();System.gc();
            return new Image(javax.microedition.lcdui.Image.createRGBImage(rgb, width, height, true));
        }
    }
    
    /**
     * creates and buffered Image
     * 
     * @param width the image width
     * @param height the image height
     * @return an image in a given width and height dimension
     */
    public static Image createImage(int width, int height){
        try {
            return new Image(javax.microedition.lcdui.Image.createImage(width, height));
        } catch(OutOfMemoryError err) {
            // Images have a major bug on many phones where they sometimes throw 
            // an OOM with no reason. A system.gc followed by the same call over
            // solves the problem. This has something to do with the fact that 
            // there is no Image.dispose method in existance.
            System.gc();System.gc();
            return new Image(javax.microedition.lcdui.Image.createImage(width, height));
        }
    }
    
    
    /**
     * creates an image from a given byte array data
     * 
     * @param bytes the array of image data in a supported image format
     * @param offset the offset of the start of the data in the array
     * @param len the length of the data in the array
     */
    public static Image createImage(byte[] bytes,int offset,int len) {
        try {
            return new Image(javax.microedition.lcdui.Image.createImage(bytes, offset, len));
        } catch(OutOfMemoryError err) {
            // Images have a major bug on many phones where they sometimes throw 
            // an OOM with no reason. A system.gc followed by the same call over
            // solves the problem. This has something to do with the fact that 
            // there is no Image.dispose method in existance.
            System.gc();System.gc();
            return new Image(javax.microedition.lcdui.Image.createImage(bytes, offset, len));
        }
    }

    /**
     * If this is a mutable image a grpahics object allowing us to draw on it
     * is returned.
     * 
     * @return Graphics object allowing us to manipulate the content of a mutable image
     */
    public Graphics getGraphics() {
        if(g == null) {
            g = new Graphics();
            g.setGraphics(image.getGraphics());
        }
        return g;
    }
    
    /**
     * Returns the width of the image
     * 
     * @return the width of the image
     */
    public int getWidth() {
        return image.getWidth();
    }
    
    /**
     * Returns the height of the image
     * 
     * @return the height of the image
     */
    public int getHeight() {
        return image.getHeight();
    }
    
    void drawImage(Graphics g, int x, int y) {
       g.drawImage(image, x, y, transform);
    }
    
    /**
     * Obtains ARGB pixel data from the specified region of this image and 
     * stores it in the provided array of integers. Each pixel value is 
     * stored in 0xAARRGGBB format, where the high-order byte contains the 
     * alpha channel and the remaining bytes contain color components for red, 
     * green and blue, respectively. The alpha channel specifies the opacity of 
     * the pixel, where a value of 0x00  represents a pixel that is fully 
     * transparent and a value of 0xFF  represents a fully opaque pixel. 
     * The rgb information contained within the image, this method ignors 
     * rotation and mirroring in some/most situations and cannot be 
     * used in such cases.
     * 
     * @param rgbData an array of integers in which the ARGB pixel data is 
     * stored
     * @param offset the index into the array where the first ARGB value is 
     * stored
     * @param scanlength the relative offset in the array between 
     * corresponding pixels in consecutive rows of the region
     * @param x the x-coordinate of the upper left corner of the region
     * @param y the y-coordinate of the upper left corner of the region
     * @param width the width of the region
     * @param height the height of the region
     */
    void getRGB(int[] rgbData,
            int offset,
            int scanlength,
            int x,
            int y,
            int width,
            int height){
        image.getRGB(rgbData, offset, scanlength, x, y, width, height);
    }

    /**
     * Extracts data from this image into the given RGBImage
     * 
     * @param image RGBImage that would receive pixel data
     * @param destX x location within RGBImage into which the data will
     *      be written
     * @param destY y location within RGBImage into which the data will
     *      be written
     * @param x location within the source image
     * @param y location within the source image
     * @param width size of the image to extract from the source image
     * @param height size of the image to extract from the source image
     */
    public void toRGB(RGBImage image,
            int destX,
            int destY,
            int x,
            int y,
            int width,
            int height){
        getRGB(image.getRGB(), destX * destY, width, x, y, width, height);
    }
    
    /**
     * Returns the content of this image as a newly created ARGB array.
     * 
     * @return new array instance containing the ARGB data within this image
     */
    public int[] getRGB() {
        int width = getWidth();
        int height = getHeight();
        int[] rgbData = new int[width * height];
        getRGB(rgbData, 0, width, 0, 0, width, height);
        return rgbData;
    }
    
    /**
     * Scales the image to the given width while updating the height based on the
     * aspect ratio of the width
     * 
     * @param width the given new image width
     */
    public Image scaledWidth(int width) {
        float ratio = ((float)width) / ((float)getWidth());
        return scaled(width, (int)(getHeight() * ratio));
    }

    /**
     * Scales the image to the given height while updating the width based on the
     * aspect ratio of the height
     * 
     * @param height the given new image height
     */
    public Image scaledHeight(int height) {
        float ratio = ((float)height) / ((float)getHeight());
        return scaled((int)(getWidth() * ratio), height);
    }
    
    /**
     * Scales the image while mainting the aspect ratio to the smaller size 
     * image
     * 
     * @param width the given new image width
     * @param height the given new image height
     */
    public Image scaledSmallerRatio(int width, int height) {
        float hRatio = ((float)height) / ((float)getHeight());
        float wRatio = ((float)width) / ((float)getWidth());
        if(hRatio < wRatio) {
            return scaled(width, (int)(getHeight() * hRatio));
        } else {
            return scaled((int)(getWidth() * wRatio), height);
        }
    }

    /**
     * Returns a scaled version of this image image using the given width and height, 
     * this is a fast algorithm that preserves transulcent information
     * 
     * @param width width for the scaling
     * @param height height of the scaled image
     * @return new image instance scaled to the given height and width
     */
    public Image scaled(int width, int height) {
        if(width == image.getWidth() && height == image.getHeight()) {
            return this;
        }
        Dimension d = new Dimension(width, height);
        Image i = getCachedImage(d);
        if(i != null) {
            return i;
        }
        i = new Image(this.image);
        i.scale(width, height);
        i.transform = this.transform;
        cacheImage(d, i);
        return i;
    }
    
    /**
     * Scale the image to the given width and height, this is a fast algorithm
     * that preserves transulcent information
     * 
     * @param width width for the scaling
     * @param height height of the scaled image
     * 
     * @deprecated scale should return an image rather than modify the image in place
     * use scaled(int, int) instead
     */
    public void scale(int width, int height) {
        int srcWidth = image.getWidth();
        int srcHeight = image.getHeight();

        // no need to scale
        if(srcWidth == width && srcHeight == height){
            return;
        }

        int[] currentArray = new int[srcWidth];
        int[] destinationArray = new int[width * height];
        opaque = scaleArray(srcWidth, srcHeight, height, width, currentArray, destinationArray);

        // if an image is opaque use a mutable image since on the device it takes 
        // far less memory
        if(opaque) {
            image = javax.microedition.lcdui.Image.createImage(width, height);
            javax.microedition.lcdui.Graphics g = image.getGraphics();
            g.drawRGB(destinationArray, 0, width, 0, 0, width, height, false);
        } else {
            image = javax.microedition.lcdui.Image.createRGBImage(destinationArray, width, height, true);
        }
    }//resize image
    
    javax.microedition.lcdui.Image getImage() {
        return image;
    }
    
    boolean scaleArray(int srcWidth, int srcHeight, int height, int width, int[] currentArray, int[] destinationArray) {
        // Horizontal Resize
        int yRatio = (srcHeight << 16) / height;
        int xRatio = (srcWidth << 16) / width;
        int xPos = xRatio / 2;
        int yPos = yRatio / 2;

        // if there is more than 16bit color there is no point in using mutable
        // images since they won't save any memory
        boolean opaque = Display.getInstance().numColors() <= 65536;
        for (int y = 0; y < height; y++) {
            int srcY = yPos >> 16;
            getRGB(currentArray, 0, srcWidth, 0, srcY, srcWidth, 1);
            for (int x = 0; x < width; x++) {
                int srcX = xPos >> 16;
                int destPixel = x + y * width;
                if ((destPixel >= 0 && destPixel < destinationArray.length) && (srcX < currentArray.length)) {
                    destinationArray[destPixel] = currentArray[srcX];

                    // if all the pixels have an opaque alpha channel then the image is opaque
                    opaque = opaque && (currentArray[srcX] & 0xff000000) == 0xff000000;
                }
                xPos += xRatio;
            }
            yPos += yRatio;
            xPos = xRatio / 2;
        }
        this.opaque = opaque;
        return opaque;
    }
    
    /**
     * Returns true if this is an animated image
     */
    public boolean isAnimation() {
        return false;
    }

    private void testOpaque(int[] rgb) {
        if(!opaqueTested) {
            opaque = true;
            for(int iter = 0 ; iter < rgb.length ; iter++) {
                if((rgb[iter] & 0xff000000) != 0xff000000) {
                    opaque = false;
                    break;
                }
            }
            opaqueTested = true;
        }
    }
    
    /**
     * Indicates whether this image is opaque or not
     * 
     * @return true if the image is completely opqaque which allows for some heavy optimizations
     */
    public boolean isOpaque() {
        if(!opaqueTested) {
            testOpaque(getRGB());
        }
        return opaque;
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?