📄 bmpimagewriter.java
字号:
if (colorModel instanceof IndexColorModel) { icm = (IndexColorModel)colorModel; } } else { // handle BI_RGB compression if (colorModel instanceof IndexColorModel) { isPalette = true; icm = (IndexColorModel)colorModel; paletteEntries = icm.getMapSize(); if (paletteEntries <= 2) { bitsPerPixel = 1; destScanlineBytes = w + 7 >> 3; } else if (paletteEntries <= 16) { bitsPerPixel = 4; destScanlineBytes = w + 1 >> 1; } else if (paletteEntries <= 256) { bitsPerPixel = 8; } else { // Cannot be written as a Palette image. So write out as // 24 bit image. bitsPerPixel = 24; isPalette = false; paletteEntries = 0; destScanlineBytes = w * 3; } if (isPalette == true) { r = new byte[paletteEntries]; g = new byte[paletteEntries]; b = new byte[paletteEntries]; a = new byte[paletteEntries]; icm.getAlphas(a); icm.getReds(r); icm.getGreens(g); icm.getBlues(b); } } else { // Grey scale images if (numBands == 1) { isPalette = true; paletteEntries = 256; bitsPerPixel = sampleSize[0]; destScanlineBytes = (w * bitsPerPixel + 7 >> 3); r = new byte[256]; g = new byte[256]; b = new byte[256]; a = new byte[256]; for (int i = 0; i < 256; i++) { r[i] = (byte)i; g[i] = (byte)i; b[i] = (byte)i; a[i] = (byte)255; } } else { if (sampleModel instanceof SinglePixelPackedSampleModel && noSubband) { /* NB: the actual pixel size can be smaller than * size of used DataBuffer element. * For example: in case of TYPE_INT_RGB actual pixel * size is 24 bits, but size of DataBuffere element * is 32 bits */ int[] sample_sizes = sampleModel.getSampleSize(); bitsPerPixel = 0; for (int size : sample_sizes) { bitsPerPixel += size; } bitsPerPixel = roundBpp(bitsPerPixel); if (bitsPerPixel != DataBuffer.getDataTypeSize(sampleModel.getDataType())) { noTransform = false; } destScanlineBytes = w * bitsPerPixel + 7 >> 3; } } } } // actual writing of image data int fileSize = 0; int offset = 0; int headerSize = 0; int imageSize = 0; int xPelsPerMeter = 0; int yPelsPerMeter = 0; int colorsUsed = 0; int colorsImportant = paletteEntries; // Calculate padding for each scanline int padding = destScanlineBytes % 4; if (padding != 0) { padding = 4 - padding; } // FileHeader is 14 bytes, BitmapHeader is 40 bytes, // add palette size and that is where the data will begin offset = 54 + paletteEntries * 4; imageSize = (destScanlineBytes + padding) * h; fileSize = imageSize + offset; headerSize = 40; long headPos = stream.getStreamPosition(); writeFileHeader(fileSize, offset); writeInfoHeader(headerSize, bitsPerPixel); // compression stream.writeInt(compressionType); // imageSize stream.writeInt(imageSize); // xPelsPerMeter stream.writeInt(xPelsPerMeter); // yPelsPerMeter stream.writeInt(yPelsPerMeter); // Colors Used stream.writeInt(colorsUsed); // Colors Important stream.writeInt(colorsImportant); // palette if (isPalette == true) { // write palette if (compressionType == BMPConstants.BI_BITFIELDS) { // write masks for red, green and blue components. for (int i=0; i<3; i++) { int mask = (a[i]&0xFF) + ((r[i]&0xFF)*0x100) + ((g[i]&0xFF)*0x10000) + ((b[i]&0xFF)*0x1000000); stream.writeInt(mask); } } else { for (int i=0; i<paletteEntries; i++) { stream.writeByte(b[i]); stream.writeByte(g[i]); stream.writeByte(r[i]); stream.writeByte(a[i]); } } } // Writing of actual image data int scanlineBytes = w * numBands; // Buffer for up to 8 rows of pixels int[] pixels = new int[scanlineBytes * scaleX]; // Also create a buffer to hold one line of the data // to be written to the file, so we can use array writes. bpixels = new byte[destScanlineBytes]; int l; if (compressionType == BMPConstants.BI_JPEG || compressionType == BMPConstants.BI_PNG) { // prepare embedded buffer embedded_stream = new ByteArrayOutputStream(); writeEmbedded(image, bmpParam); // update the file/image Size embedded_stream.flush(); imageSize = embedded_stream.size(); long endPos = stream.getStreamPosition(); fileSize = (int)(offset + imageSize); stream.seek(headPos); writeSize(fileSize, 2); stream.seek(headPos); writeSize(imageSize, 34); stream.seek(endPos); stream.write(embedded_stream.toByteArray()); embedded_stream = null; if (abortRequested()) { processWriteAborted(); } else { processImageComplete(); stream.flushBefore(stream.getStreamPosition()); } return; } isTopDown = bmpParam.isTopDown(); int maxBandOffset = bandOffsets[0]; for (int i = 1; i < bandOffsets.length; i++) if (bandOffsets[i] > maxBandOffset) maxBandOffset = bandOffsets[i]; int[] pixel = new int[maxBandOffset + 1]; int destScanlineLength = destScanlineBytes; if (noTransform && noSubband) { destScanlineLength = destScanlineBytes / (DataBuffer.getDataTypeSize(dataType)>>3); } for (int i = 0; i < h; i++) { if (abortRequested()) { break; } int row = minY + i; if (!isTopDown) row = minY + h - i -1; // Get the pixels Raster src = inputRaster; Rectangle srcRect = new Rectangle(minX * scaleX + xOffset, row * scaleY + yOffset, (w - 1)* scaleX + 1, 1); if (!writeRaster) src = input.getData(srcRect); if (noTransform && noSubband) { SampleModel sm = src.getSampleModel(); int pos = 0; int startX = srcRect.x - src.getSampleModelTranslateX(); int startY = srcRect.y - src.getSampleModelTranslateY(); if (sm instanceof ComponentSampleModel) { ComponentSampleModel csm = (ComponentSampleModel)sm; pos = csm.getOffset(startX, startY, 0); for(int nb=1; nb < csm.getNumBands(); nb++) { if (pos > csm.getOffset(startX, startY, nb)) { pos = csm.getOffset(startX, startY, nb); } } } else if (sm instanceof MultiPixelPackedSampleModel) { MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel)sm; pos = mppsm.getOffset(startX, startY); } else if (sm instanceof SinglePixelPackedSampleModel) { SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel)sm; pos = sppsm.getOffset(startX, startY); } if (compressionType == BMPConstants.BI_RGB || compressionType == BMPConstants.BI_BITFIELDS){ switch(dataType) { case DataBuffer.TYPE_BYTE: byte[] bdata = ((DataBufferByte)src.getDataBuffer()).getData(); stream.write(bdata, pos, destScanlineLength); break; case DataBuffer.TYPE_SHORT: short[] sdata = ((DataBufferShort)src.getDataBuffer()).getData(); stream.writeShorts(sdata, pos, destScanlineLength); break; case DataBuffer.TYPE_USHORT: short[] usdata = ((DataBufferUShort)src.getDataBuffer()).getData(); stream.writeShorts(usdata, pos, destScanlineLength); break; case DataBuffer.TYPE_INT: int[] idata = ((DataBufferInt)src.getDataBuffer()).getData(); stream.writeInts(idata, pos, destScanlineLength); break; } for(int k=0; k<padding; k++) { stream.writeByte(0); } } else if (compressionType == BMPConstants.BI_RLE4) { if (bpixels == null || bpixels.length < scanlineBytes) bpixels = new byte[scanlineBytes]; src.getPixels(srcRect.x, srcRect.y, srcRect.width, srcRect.height, pixels); for (int h=0; h<scanlineBytes; h++) { bpixels[h] = (byte)pixels[h]; } encodeRLE4(bpixels, scanlineBytes); } else if (compressionType == BMPConstants.BI_RLE8) { //byte[] bdata = // ((DataBufferByte)src.getDataBuffer()).getData(); //System.out.println("bdata.length="+bdata.length); //System.arraycopy(bdata, pos, bpixels, 0, scanlineBytes); if (bpixels == null || bpixels.length < scanlineBytes) bpixels = new byte[scanlineBytes]; src.getPixels(srcRect.x, srcRect.y, srcRect.width, srcRect.height, pixels); for (int h=0; h<scanlineBytes; h++) { bpixels[h] = (byte)pixels[h]; } encodeRLE8(bpixels, scanlineBytes); } } else { src.getPixels(srcRect.x, srcRect.y, srcRect.width, srcRect.height, pixels); if (scaleX != 1 || maxBandOffset != numBands - 1) { for (int j = 0, k = 0, n=0; j < w; j++, k += scaleX * numBands, n += numBands) { System.arraycopy(pixels, k, pixel, 0, pixel.length); for (int m = 0; m < numBands; m++) { // pixel data is provided here in RGB order pixels[n + m] = pixel[sourceBands[m]]; } } } writePixels(0, scanlineBytes, bitsPerPixel, pixels, padding, numBands, icm); } processImageProgress(100.0f * (((float)i) / ((float)h))); } if (compressionType == BMPConstants.BI_RLE4 || compressionType == BMPConstants.BI_RLE8) { // Write the RLE EOF marker and stream.writeByte(0); stream.writeByte(1); incCompImageSize(2); // update the file/image Size imageSize = compImageSize; fileSize = compImageSize + offset; long endPos = stream.getStreamPosition(); stream.seek(headPos); writeSize(fileSize, 2); stream.seek(headPos); writeSize(imageSize, 34); stream.seek(endPos); } if (abortRequested()) { processWriteAborted(); } else { processImageComplete(); stream.flushBefore(stream.getStreamPosition()); } } private void writePixels(int l, int scanlineBytes, int bitsPerPixel, int pixels[], int padding, int numBands, IndexColorModel icm) throws IOException { int pixel = 0; int k = 0; switch (bitsPerPixel) { case 1: for (int j=0; j<scanlineBytes/8; j++) { bpixels[k++] = (byte)((pixels[l++] << 7) | (pixels[l++] << 6) | (pixels[l++] << 5) | (pixels[l++] << 4) | (pixels[l++] << 3) | (pixels[l++] << 2) | (pixels[l++] << 1) | pixels[l++]); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -