Imagepublic class Image extends Object The Image class is used to hold graphical image
data. Image
objects exist independently of the display device. They exist only in
off-screen memory and will not be painted on the display unless an explicit
command is issued by the application (such as within the
paint() method of
a Canvas ) or when an Image object is
placed within a Form screen or an
Alert screen and that screen is made current.
Images are either mutable or immutable depending upon
how they are created. Immutable images are generally created by loading
image data from resource bundles, from files, or from the network. They may
not be modified once created. Mutable images are created as blank images
containing only white pixels. The application may render on a mutable image
by calling {@link #getGraphics} on the Image to obtain
a Graphics object
expressly for this purpose.
Images may be placed within Alert ,
Choice , Form , or ImageItem
objects.
The high-level user interface implementation may need to update the display
at any time, without notifying the application. In order to provide
predictable behavior, the high-level user interface
objects provide snapshot semantics for the image. That is, when a mutable
image is placed within an Alert , Choice ,
Form , or ImageItem object,
the effect is as if a snapshot is taken of its current contents. This
snapshot is then used for all subsequent painting of the high-level user
interface component. If the application modifies the contents of the
image, the application must update the component containing the image (for
example, by calling ImageItem.setImage ) in order to
make the modified
contents visible.
An immutable image may be created from a mutable image through the
use of the {@link #createImage(Image) createImage} method. It is possible
to create a mutable copy of an immutable image using a technique similar
to the following:
Image source; // the image to be copied
source = Image.createImage(...);
Image copy = Image
.createImage(source.getWidth(), source.getHeight());
Graphics g = copy.getGraphics();
g.drawImage(source, 0, 0, TOP|LEFT);
|
Alpha Processing
Every pixel within a mutable image is always fully opaque. Immutable
images may contain a combination of fully opaque pixels
(alpha = 2bitdepth - 1) , fully
transparent pixels (alpha = 0 ), and
semitransparent pixels
(0 < alpha <
2bitdepth - 1 ),
where bitdepth is the number of bits per sample in the source data.
Implementations must support storage, processing, and rendering of fully
opaque pixels and fully transparent pixels in immutable images. When
creating an image from source data (whether from a PNG file or from an
array of ARGB data), a fully opaque pixel in the source data must always
result in a fully opaque pixel in the new image, and a fully transparent
pixel in the source data must always result in a fully transparent pixel in
the new image.
The required treatment of semitransparent pixel data depends upon
whether the implementation supports alpha blending at rendering time. If
the implementation supports alpha blending, a semitransparent pixel in the
source data must result in a semitransparent pixel in the new image. The
resulting alpha value may be modified to accommodate the number of levels
of semitransparency supported by the platform. (See the {@link
Display#numAlphaLevels() Display.numAlphaLevels()} method.) If an
implementation does not support alpha blending, any semitransparent pixels
in the source data must be replaced with fully transparent pixels in the
new image.
PNG Image Format
Implementations are required to support images stored in the PNG format,
as specified by the PNG (Portable Network Graphics) Specification,
Version 1.0. All conforming MIDP implementations are also conformant
to the minimum set of requirements given by the PNG Specification.
MIDP implementations also must conform to additional requirements given
here with respect to handling of PNG images. Note that the requirements
listed here take precedence over any conflicting recommendations given in
the PNG Specification.
Critical Chunks
All of the 'critical' chunks specified by PNG must be supported. The
paragraphs below describe these critical chunks.
The IHDR chunk. MIDP devices must handle the following values in
the IHDR chunk:
- All positive values of width and height are supported; however, a
very large image may not be readable because of memory constraints. The
dimensions of the resulting
Image object must match
the dimensions of the PNG image. That is, the values returned by
{@link #getWidth() getWidth()} and {@link #getHeight() getHeight()}
and the rendered width and height must
equal the width and height specified in the IHDR chunk.
- All color types are supported, although the appearance of the image will
be dependent on the capabilities of the device's screen. Color types that
include alpha channel data are supported.
- For color types
4 & 6 (grayscale
with alpha and RGB with alpha,
respectively) the alpha channel must be decoded. Any pixels with an alpha
value of zero must be treated as transparent. Any pixels with an alpha
value of 255 (for images with 8 bits per
sample) or 65535 (for images with
16 bits per sample) must be treated as opaque. If
rendering with alpha
blending is supported, any pixels with intermediate alpha values must be
carried through to the resulting image. If alpha blending is not
supported, any pixels with intermediate alpha values must be replaced with
fully transparent pixels.
- All bit depth values for the given color type are supported.
- Compression method
0 (deflate) is the only
supported compression method.
This method utilizes the "zlib" compression scheme, which
is also used for
jar files; thus, the decompression (inflate) code may be shared between the
jar decoding and PNG decoding implementations. As noted in the PNG
specification, the compressed data stream may comprised internally of both
compressed and uncompressed (raw) data.
- The filter method represents a series of encoding schemes that may be
used to optimize compression. The PNG spec currently defines a single
filter method (method
0 ) that is an adaptive filtering
scheme with five
basic filter types. Filtering is essential for optimal compression since it
allows the deflate algorithm to exploit spatial similarities within the
image. Therefore, MIDP devices must support all five filter types defined
by filter method 0 .
- MIDP devices are required to read PNG images that are encoded with
either interlace method
0 (None) or interlace method
1 (Adam7). Image
loading in MIDP is synchronous and cannot be overlapped with image
rendering, and so there is no advantage for an application to use interlace
method 1 . Support for decoding interlaced images is
required for
compatibility with PNG and for the convenience of developers who may already
have interlaced images available.
The PLTE chunk. Palette-based images must be supported.
The IDAT chunk. Image data may be encoded using any of the
5 filter
types defined by filter method 0 (None, Sub, Up,
Average, Paeth).
The IEND chunk. This chunk must be found in order for the image to be
considered valid.
Ancillary Chunks
PNG defines several 'ancillary' chunks that may be present in a
PNG image but are not critical for image decoding.
The tRNS chunk. All implementations must support the tRNS chunk.
This chunk is used to implement transparency without providing alpha
channel data for each pixel. For color types 0 and
2 , a particular
gray or RGB value is defined to be a transparent pixel. In this case, the
implementation must treat pixels with this value as fully transparent.
Pixel value comparison must be based on the actual pixel values using the
original sample depth; that is, this comparison must be performed before
the pixel values are resampled to reflect the display capabilities
of the device. For color type 3 (indexed color),
8 -bit alpha values are
potentially provided for each entry in the color palette. In this case,
the implementation must treat pixels with an alpha value of
0 as fully
transparent, and it must treat pixels with an alpha value of
255 as fully
opaque. If rendering with alpha blending is supported, any pixels with
intermediate alpha values must be carried through to the resulting image.
If alpha blending is not supported, any pixels with intermediate alpha
values must be replaced with fully transparent pixels.
The implementation may (but is not required to) support
any of the other ancillary chunks. The implementation must
silently ignore any unsupported ancillary chunks that it encounters.
The currently defined optional ancillary chunks are:
cHRM gAMA hIST iCCP iTXt pHYs
sBIT sPLT sRGB tEXt tIME zTXt
Reference
PNG (Portable Network Graphics) Specification, Version 1.0.
W3C Recommendation, October 1, 1996. http://www.w3.org/TR/REC-png.html.
Also available as RFC 2083, http://www.ietf.org/rfc/rfc2083.txt. |
Fields Summary |
---|
private int | widthWidth of the image in pixels. | private int | heightHeight of the image in pixels. | private final boolean | isMutableIf this Image is mutable. | private final com.sun.me.gci.surface.GCIDrawingSurface | gciDrawingSurfaceGCIDrawingSurface instance associated with this Image. | static final int | INVALID_TRANSFORM_BITSValid transforms possible are 0 - 7 | static final int | TRANSFORM_SWAP_AXISTransform swap axis bit is the 3 bit |
Constructors Summary |
---|
private Image(int width, int height, boolean isMutable, com.sun.me.gci.surface.GCIDrawingSurface gciDrawingSurface)Creates an Immutable image from the given ImageData.
this.width = width;
this.height = height;
this.isMutable = isMutable;
this.gciDrawingSurface = gciDrawingSurface;
| private Image(int width, int height, boolean isMutable)Creates an Immutable image from the given ImageData.
this.width = width;
this.height = height;
this.isMutable = isMutable;
GCIDisplay display=
GCIGraphicsEnvironment.getInstance().getDefaultDisplay();
gciDrawingSurface = display.createOffscreenDrawingSurface(width,
height,
GCIDrawingSurface.FORMAT_ARGB_8888);
|
Methods Summary |
---|
public static javax.microedition.lcdui.Image | createImage(int width, int height)Creates a new, mutable image for off-screen drawing. Every pixel
within the newly created image is white. The width and height of the
image must both be greater than zero.
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException();
}
// SYNC NOTE: Not accessing any shared data, no locking necessary
return new Image(width, height, true);
| public static javax.microedition.lcdui.Image | createImage(javax.microedition.lcdui.Image source)Creates an immutable image from a source image.
If the source image is mutable, an immutable copy is created and
returned. If the source image is immutable, the implementation may
simply return it without creating a new image. If an immutable source
image contains transparency information, this information is copied to
the new image unchanged.
This method is useful for placing the contents of mutable images
into Choice objects. The application can create
an off-screen image
using the
{@link #createImage(int, int) createImage(w, h)}
method, draw into it using a Graphics object
obtained with the
{@link #getGraphics() getGraphics()}
method, and then create an immutable copy of it with this method.
The immutable copy may then be placed into Choice
objects.
// SYNC NOTE: Not accessing any shared data, no locking necessary
if (source.isMutable()) {
return new Image(source.getWidth(), source.getHeight(), false,
null /* TODO add impl */);
} else {
return source;
}
| public static javax.microedition.lcdui.Image | createImage(java.lang.String name)Creates an immutable image from decoded image data obtained from the
named resource. The name parameter is a resource name as defined by
{@link Class#getResourceAsStream(String)
Class.getResourceAsStream(name)}. The rules for resolving resource
names are defined in the
Application Resource Files section of the
java.lang package documentation.
return new Image(0, 0, false,
null /* TODO - add impl */);
| public static javax.microedition.lcdui.Image | createImage(byte[] imageData, int imageOffset, int imageLength)Creates an immutable image which is decoded from the data stored in
the specified byte array at the specified offset and length. The data
must be in a self-identifying image file format supported by the
implementation, such as PNG.
The imageoffset and imagelength
parameters specify a range of
data within the imageData byte array. The
imageOffset parameter
specifies the
offset into the array of the first data byte to be used. It must
therefore lie within the range
[0..(imageData.length-1)] . The
imageLength
parameter specifies the number of data bytes to be used. It must be a
positive integer and it must not cause the range to extend beyond
the end
of the array. That is, it must be true that
imageOffset + imageLength < imageData.length .
This method is intended for use when loading an
image from a variety of sources, such as from
persistent storage or from the network.
if (imageOffset < 0 || imageOffset >= imageData.length ||
imageLength < 0 ||
imageOffset + imageLength > imageData.length) {
throw new ArrayIndexOutOfBoundsException();
}
return new Image(0, 0, false/* TODO - add impl */);
| public static javax.microedition.lcdui.Image | createImage(javax.microedition.lcdui.Image image, int x, int y, int width, int height, int transform)Creates an immutable image using pixel data from the specified
region of a source image, transformed as specified.
The source image may be mutable or immutable. For immutable source
images, transparency information, if any, is copied to the new
image unchanged.
On some devices, pre-transformed images may render more quickly
than images that are transformed on the fly using
drawRegion .
However, creating such images does consume additional heap space,
so this technique should be applied only to images whose rendering
speed is critical.
The transform function used must be one of the following, as defined
in the {@link javax.microedition.lcdui.game.Sprite Sprite} class:
Sprite.TRANS_NONE - causes the specified image
region to be copied unchanged
Sprite.TRANS_ROT90 - causes the specified image
region to be rotated clockwise by 90 degrees.
Sprite.TRANS_ROT180 - causes the specified image
region to be rotated clockwise by 180 degrees.
Sprite.TRANS_ROT270 - causes the specified image
region to be rotated clockwise by 270 degrees.
Sprite.TRANS_MIRROR - causes the specified image
region to be reflected about its vertical center.
Sprite.TRANS_MIRROR_ROT90 - causes the specified image
region to be reflected about its vertical center and then rotated
clockwise by 90 degrees.
Sprite.TRANS_MIRROR_ROT180 - causes the specified image
region to be reflected about its vertical center and then rotated
clockwise by 180 degrees.
Sprite.TRANS_MIRROR_ROT270 - causes the specified image
region to be reflected about its vertical center and then rotated
clockwise by 270 degrees.
The size of the returned image will be the size of the specified region
with the transform applied. For example, if the region is
100 x 50 pixels and the transform is
TRANS_ROT90 , the
returned image will be 50 x 100 pixels.
Note: If all of the following conditions
are met, this method may
simply return the source Image without creating a
new one:
- the source image is immutable;
- the region represents the entire source image; and
- the transform is
TRANS_NONE .
if ((transform & INVALID_TRANSFORM_BITS) != 0) {
throw new IllegalArgumentException();
}
if (x < 0 || y < 0 ||
(x + width) > image.getWidth() || // throws NPE if image is null
(y + height) > image.getHeight() ||
width <= 0 || height <= 0) {
throw new IllegalArgumentException();
}
if (x == 0 && y == 0
&& width == image.getWidth() && height == image.getHeight()
&& transform == Sprite.TRANS_NONE) {
return null /* TODO add impl */;
} else {
return
new Image(width, height, false,
null /* TODO add impl */);
}
| com.sun.me.gci.surface.GCIDrawingSurface | getDrawingSurface()Returns GCIDrawingSurface associated with this
Image .
return gciDrawingSurface;
| public Graphics | getGraphics()Creates a new Graphics object that renders to this
image. This image
must be
mutable; it is illegal to call this method on an immutable image.
The mutability of an image may be tested
with the isMutable() method.
The newly created Graphics object has the
following properties:
- the destination is this
Image object;
- the clip region encompasses the entire
Image ;
- the current color is black;
- the font is the same as the font returned by
{@link Font#getDefaultFont() Font.getDefaultFont()};
- the stroke style is {@link Graphics#SOLID SOLID}; and
- the origin of the coordinate system is located at the upper-left
corner of the Image.
The lifetime of Graphics objects created using
this method is
indefinite. They may be used at any time, by any thread.
if (isMutable()) {
// SYNC NOTE: no locking necessary as getGraphics() only allocates
// a new object
return Graphics.getImageGraphics(this);
} else {
// SYNC NOTE: Not accessing any shared data, no locking necessary
throw new IllegalStateException();
}
| public int | getHeight()Gets the height of the image in pixels. The value returned
must reflect the actual height of the image when rendered.
return height;
| javax.microedition.lcdui.ImageData | getImageData()Returns ImageData associated with this
Image .
return null;
| public void | getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height)
gciDrawingSurface.getPixels(x, y, width, height,
rgbData, offset, scanlength);
| static javax.microedition.lcdui.Image | getRomizedImage(int imageDataArrayPtr, int imageDataArrayLength)Function to load an romized Image.
// TODO -add impl
return null;
| public int | getWidth()Gets the width of the image in pixels. The value returned
must reflect the actual width of the image when rendered.
return width;
| public boolean | isMutable()Check if this image is mutable. Mutable images can be modified by
rendering to them through a Graphics object
obtained from the
getGraphics() method of this object.
return isMutable;
| void | resize(int width, int height, boolean keepContent)Resize Image optionally saving its content clipped according
to the new geometry
if (!isMutable || width <= 0 || height <= 0) {
throw new IllegalArgumentException();
}
// IMPL_NOTE: In the case content is not kept it is possible
// to resize the image more efficiently, especially for the
// case of rotation, when the memory reallocation is not needed.
// However, now there are no scenarios when resize is needed
// without content saving.
Image newImage = createImage(width, height);
synchronized(this) {
if (keepContent) {
// GCI - TODO
// render(Graphics.getImageGraphics(newImage), 0, 0,
// Graphics.TOP | Graphics.LEFT);
}
this.width = width;
this.height = height;
}
|
|