/// <summary> /// Writes the <tt>IconEntry</tt> structure to output /// </summary> private int WriteIconEntry(BufferedImage img, int fileOffset) { // Width 1 byte Cursor Width (16, 32 or 64) int width = img.getWidth(); writer.Write((byte)(width == 256 ? 0 : width)); // Height 1 byte Cursor Height (16, 32 or 64 , most commonly = Width) int height = img.getHeight(); writer.Write((byte)(height == 256 ? 0 : height)); // ColorCount 1 byte Number of Colors (2,16, 0=256) short BitCount = (short)img.getColorModel().getPixelSize(); int NumColors = 1 << (BitCount == 32 ? 24 : (int)BitCount); byte ColorCount = (byte)(NumColors >= 256 ? 0 : NumColors); writer.Write((byte)ColorCount); // Reserved 1 byte =0 writer.Write((byte)0); // Planes 2 byte =1 writer.Write((short)1); // BitCount 2 byte bits per pixel (1, 4, 8) writer.Write((short)BitCount); // SizeInBytes 4 byte Size of (InfoHeader + ANDbitmap + XORbitmap) int cmapSize = GetColorMapSize(BitCount); int xorSize = GetBitmapSize(width, height, BitCount); int andSize = GetBitmapSize(width, height, 1); int size = 40 + cmapSize + xorSize + andSize; writer.Write(size); // FileOffset 4 byte FilePos, where InfoHeader starts writer.Write(fileOffset); return(size); }
/** * @see Graphics2D#drawImage(BufferedImage, BufferedImageOp, int, int) */ public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { BufferedImage result = op.createCompatibleDestImage(img, img.getColorModel()); result = op.filter(img, result); drawImage(result, x, y, null); }
/// <summary> /// Writes the <tt>InfoHeader</tt> structure to output /// /// </summary> private void WriteInfoHeader(BufferedImage img) { // Size of InfoHeader structure = 40 writer.Write(40); // Width writer.Write(img.getWidth()); // Height writer.Write(img.getHeight() * 2); // Planes (=1) writer.Write((short)1); // Bit count writer.Write((short)img.getColorModel().getPixelSize()); // Compression writer.Write(0); // Image size - compressed size of image or 0 if Compression = 0 writer.Write(0); // horizontal resolution pixels/meter writer.Write(0); // vertical resolution pixels/meter writer.Write(0); // Colors used - number of colors actually used writer.Write(0); // Colors important - number of important colors 0 = all writer.Write(0); }
private void WriteXorBitmap(BufferedImage img) { Raster raster = img.getRaster(); switch (img.getColorModel().getPixelSize()) { case 1: Write1(raster); break; case 4: Write4(raster); break; case 8: Write8(raster); break; case 24: Write24(raster); break; case 32: Raster alpha = img.getAlphaRaster(); Write32(raster, alpha); break; } }
public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) { if (destCM == null) { destCM = src.getColorModel(); if (destCM is IndexColorModel) { destCM = ColorModel.getRGBdefault(); } } return(new BufferedImage(destCM, destCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), destCM.isAlphaPremultiplied(), null)); }
/// <summary> /// Encodes and writes multiple images without colour depth conversion. /// </summary> /// <param name="images"> /// the list of source images to be encoded </param> /// <param name="stream"> /// the output to which the encoded image will be written </param> internal void Write(java.util.List images, System.IO.Stream stream) { writer = new BinaryWriter(stream); int count = images.size(); // file header 6 WriteFileHeader(count, TYPE_ICON); // file offset where images start int fileOffset = 6 + count * 16; // icon entries 16 * count for (int i = 0; i < count; i++) { BufferedImage imgc = (BufferedImage)images.get(i); fileOffset += WriteIconEntry(imgc, fileOffset); } // images for (int i = 0; i < count; i++) { BufferedImage imgc = (BufferedImage)images.get(i); // info header WriteInfoHeader(imgc); // color map if (imgc.getColorModel().getPixelSize() <= 8) { IndexColorModel icm = (IndexColorModel)imgc.getColorModel(); WriteColorMap(icm); } // xor bitmap WriteXorBitmap(imgc); // and bitmap WriteAndBitmap(imgc); } }
/// <summary> /// Encodes the <em>AND</em> bitmap for the given image according the its /// alpha channel (transparency) and writes it to the given output. /// </summary> /// <param name="img"> /// the image to encode as the <em>AND</em> bitmap. </param> private void WriteAndBitmap(BufferedImage img) { WritableRaster alpha = img.getAlphaRaster(); // indexed transparency (eg. GIF files) if (img.getColorModel() is IndexColorModel && img.getColorModel().hasAlpha()) { int w = img.getWidth(); int h = img.getHeight(); int bytesPerLine = GetBytesPerLine1(w); byte[] line = new byte[bytesPerLine]; IndexColorModel icm = (IndexColorModel)img.getColorModel(); Raster raster = img.getRaster(); for (int y = h - 1; y >= 0; y--) { for (int x = 0; x < w; x++) { int bi = x / 8; int i = x % 8; // int a = alpha.getSample(x, y, 0); int p = raster.getSample(x, y, 0); int a = icm.getAlpha(p); // invert bit since and mask is applied to xor mask int b = ~a & 1; line[bi] = SetBit(line[bi], i, b); } writer.Write(line); } } // no transparency else if (alpha == null) { int h = img.getHeight(); int w = img.getWidth(); // calculate number of bytes per line, including 32-bit padding int bytesPerLine = GetBytesPerLine1(w); byte[] line = new byte[bytesPerLine]; for (int i = 0; i < bytesPerLine; i++) { line[i] = (byte)0; } for (int y = h - 1; y >= 0; y--) { writer.Write(line); } } // transparency (ARGB, etc. eg. PNG) else { int w = img.getWidth(); int h = img.getHeight(); int bytesPerLine = GetBytesPerLine1(w); byte[] line = new byte[bytesPerLine]; for (int y = h - 1; y >= 0; y--) { for (int x = 0; x < w; x++) { int bi = x / 8; int i = x % 8; int a = alpha.getSample(x, y, 0); // invert bit since and mask is applied to xor mask int b = ~a & 1; line[bi] = SetBit(line[bi], i, b); } writer.Write(line); } } }