2014-03-28 4 views
0

JAI를 사용하여 tif 이미지의 바이트 배열을 저장해야합니다. gdal에서 tif 바이트 배열을 가져 왔습니다. 나는 다음과 같은 코드가 있습니다바이트 배열의 색상을 잃지 않고 tif 파일을 저장하려면 어떻게해야합니까?

BufferedImage bufferedImage = new BufferedImage(fullWidthSize/2, fullHeightSize/2, BufferedImage.TYPE_BYTE_BINARY); 
WritableRaster raster = bufferedImage.getRaster(); 
raster.setDataElements(0, 0, fullWidthSize/2, fullHeightSize/2, bytes); 

TIFFEncodeParam params = new TIFFEncodeParam(); 
params.setCompression(TIFFEncodeParam.COMPRESSION_NONE); 
String filenametiff = "/mnt/hdfs/user/hdfs/inImage/haw2_smallJAI.tif"; 
JAI.create("filestore", bufferedImage, filenametiff, "TIFF", params); 

을하지만 불행히도 그것은 TIF 이미지를 저장하지만, 그레이 스케일에, 나 또한 노력 TYPE_BYTE_INDEXED하지만 종류의 흐린 이상한 색상으로 이미지를 저장하고, TYPE_CUSTOM를 사용하여 나는 오류를 다음 얻을 :

java.lang.IllegalArgumentException가 : 이미지가 올바르게 기록 될 수 있도록 0

당신이 나에게 몇 가지 지침을 제공하시기 바랍니다 수있는 알 수없는 이미지 유형?

P. 내가 gdal을 사용하여 이미지를 유지하지 않는 이유는 어떻게 든 "_tiffSeekProc : Operation not supported"메시지와 함께 hdfs로 쓸 수 없기 때문에 FUSE를 사용하여 hdfs를 마운트했기 때문입니다.

+1

어떤 픽셀 레이아웃이'바이트 '입니까? 'TYPE_BYTE_BINARY'는 단색 흑색/백색 이미지를 생성 할 것이고, TYPE_BYTE_INDEXED'는 미리 정의 된 팔레트와 함께 색인 된 색상 (lookup-table/palette) 타입의 이미지를 생성 할 것입니다. 이미지가 RGB 1 바이트/샘플이면 'TYPE_3BYTE_BGR'을 원할 것입니다. 또는 'ColorModel','Raster' 및'HashTable'을 사용하는'BufferedImage' 생성자를 사용하십시오 (테이블에 대해'null'전달). – haraldK

+1

귀하의 의견 haraldK 주셔서 감사합니다, 그들은 나에게 빛을 준, 마침내 TYPE_3BYTE_RGB와 함께 일을했으나, 수동으로 내 물기를 1R 1G 및 픽셀 당 1B 바이트로 주문해야했다. 원래 밴드에 의해 주문 되었기 때문에,이 트릭을 만들었다. 다시 한 번 감사드립니다! – zaz

+0

차가움. 위에서 언급 한 마지막 생성자를 사용하여 밴드 모델을 사용하는'BufferedImage'를 만들 수도 있습니다. 디스플레이 속도가 느려지 겠지만 입력을 받으면 작업하는 것이 더 편리 할 수 ​​있습니다. – haraldK

답변

0

댓글이 너무 길었습니다. 죄송합니다. ;-)

다음은 몇 가지 샘플 코드입니다. 올바르게 이해해야 도움이됩니다. 그것을 쓰고있는 재미를 가지고 있었다. ..

그것은 무엇을 만들고, 6 개의 이미지 (무작위 소음의)를 만들고 있고있다. 서로 다른 두 가지 방식으로 만들어진 3 가지 이미지가 있습니다. 4는 줄무늬 모델과 2 개의 인터리브 모델을 사용합니다. 줄무늬 모델의 경우 단일 및 다차원 배열을 사용하여 모델을 만드는 방법을 보여줍니다. 각각 왜 줄무늬 래스터 1 & 2, 3 & 4 설명과 동일하거나 같은 유형이 아닌 수있는 사람에게 보너스 포인트 :

bandedRaster1: ByteBandedRaster: width = 300 height = 200 #bands 3 minX = 0 minY = 0 
bandedRaster2: [email protected] 
bandedRaster3: ByteBandedRaster: width = 300 height = 200 #bands 3 minX = 0 minY = 0 
bandedRaster4: [email protected] 
image1: [email protected]: type = 0 ColorModel: #pixelBits = 24 numComponents = 3 color space = [email protected] transparency = 1 has alpha = false isAlphaPre = false ByteBandedRaster: width = 300 height = 200 #bands 3 minX = 0 minY = 0 
image2: [email protected]: type = 0 ColorModel: #pixelBits = 24 numComponents = 3 color space = [email protected] transparency = 1 has alpha = false isAlphaPre = false [email protected] 
image3: [email protected]: type = 0 ColorModel: #pixelBits = 24 numComponents = 3 color space = [email protected] transparency = 1 has alpha = false isAlphaPre = false ByteBandedRaster: width = 300 height = 200 #bands 3 minX = 0 minY = 0 
image4: [email protected]: type = 0 ColorModel: #pixelBits = 24 numComponents = 3 color space = [email protected] transparency = 1 has alpha = false isAlphaPre = false [email protected] 
interleavedRaster1: ByteInterleavedRaster: width = 300 height = 200 #numDataElements 3 dataOff[0] = 2 
interleavedRaster2: ByteInterleavedRaster: width = 300 height = 200 #numDataElements 3 dataOff[0] = 2 
image5: [email protected]: type = 5 ColorModel: #pixelBits = 24 numComponents = 3 color space = [email protected] transparency = 1 has alpha = false isAlphaPre = false ByteInterleavedRaster: width = 300 height = 200 #numDataElements 3 dataOff[0] = 2 
image6: [email protected]: type = 5 ColorModel: #pixelBits = 24 numComponents = 3 color space = [email protected] transparency = 1 has alpha = false isAlphaPre = false ByteInterleavedRaster: width = 300 height = 200 #numDataElements 3 dataOff[0] = 2 

PS : 여기

import java.awt.Point; 
import java.awt.Transparency; 
import java.awt.Window; 
import java.awt.color.ColorSpace; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.awt.image.BandedSampleModel; 
import java.awt.image.BufferedImage; 
import java.awt.image.ColorModel; 
import java.awt.image.ComponentColorModel; 
import java.awt.image.DataBuffer; 
import java.awt.image.DataBufferByte; 
import java.awt.image.PixelInterleavedSampleModel; 
import java.awt.image.Raster; 
import java.awt.image.WritableRaster; 
import java.util.Arrays; 
import java.util.Random; 

import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingUtilities; 
import javax.swing.WindowConstants; 

public class BufferedImageTester { 
    public static void main(String[] args) { 
     // Part I 
     // Dimensions, number of bands and other setup 
     int width = 300; 
     int height = 200; 
     int bands = 3; // 4 works too, if you want alpha 
     int bandSize = width * height; 
     Point origin = new Point(0, 0); 

     // Create backing data for single array banded model 
     byte[] singleData = new byte[bandSize * bands]; 
     int[] singleBankIndices = createIndices(bands, 0, 0); // 0, 0, 0 
     int[] singleBandOffsets = createIndices(bands, 0, bandSize); // 0, bandSize, 2 * bandSize 

     // Create buffer for single array 
     DataBufferByte singleBuffer = new DataBufferByte(singleData, singleData.length, 0); 

     // Create raster directly from buffer 
     WritableRaster bandedRaster1 = Raster.createBandedRaster(singleBuffer, width, height, width, singleBankIndices, singleBandOffsets, origin); 
     System.out.println("bandedRaster1: " + bandedRaster1); 

     // Create raster from sample model and buffer 
     BandedSampleModel singleModel = new BandedSampleModel(DataBuffer.TYPE_BYTE, width, height, width, singleBankIndices, singleBandOffsets); 
     WritableRaster bandedRaster2 = Raster.createWritableRaster(singleModel, singleBuffer, origin); 
     System.out.println("bandedRaster2: " + bandedRaster2); 

     // Create backing data for multiple arrays banded model 
     byte[][] multiData = new byte[bands][bandSize]; 
     int[] multiBankIndices = createIndices(bands, 0, 1); // 0, 1, 2 
     int[] multiBandOffsets = createIndices(bands, 0, 0); // 0, 0, 0 

     // Create buffer for multiple arrays 
     DataBufferByte multiBuffer = new DataBufferByte(multiData, bandSize, multiBandOffsets); 

     // Create raster directly from buffer 
     WritableRaster bandedRaster3 = Raster.createBandedRaster(multiBuffer, width, height, width, multiBankIndices, multiBandOffsets, origin); 
     System.out.println("bandedRaster3: " + bandedRaster3); 

     // Create raster from sample model and buffer 
     BandedSampleModel multiModel = new BandedSampleModel(DataBuffer.TYPE_BYTE, width, height, width, multiBankIndices, multiBandOffsets); 
     WritableRaster bandedRaster4 = Raster.createWritableRaster(multiModel, multiBuffer, origin); 
     System.out.println("bandedRaster4: " + bandedRaster4); 

     // Now let's create a suitable color model for these kinds of rasters, with default sRGB color space 
     ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), bands > 3, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); 

     // Create images for all of the raster types 
     BufferedImage image1 = new BufferedImage(colorModel, bandedRaster1, colorModel.isAlphaPremultiplied(), null); 
     System.out.println("image1: " + image1); 
     BufferedImage image2 = new BufferedImage(colorModel, bandedRaster2, colorModel.isAlphaPremultiplied(), null); 
     System.out.println("image2: " + image2); 
     BufferedImage image3 = new BufferedImage(colorModel, bandedRaster3, colorModel.isAlphaPremultiplied(), null); 
     System.out.println("image3: " + image3); 
     BufferedImage image4 = new BufferedImage(colorModel, bandedRaster4, colorModel.isAlphaPremultiplied(), null); 
     System.out.println("image4: " + image4); 

     // Fill with randomness to make it less dull 
     Random random = new Random(); 
     random.nextBytes(singleData); 
     for (byte[] bytes : multiData) { 
      random.nextBytes(bytes); 
     } 

     // And finally display to prove it works just fine 
     showIt(image1, "Image 1: Single bank, banded raster"); 
     showIt(image2, "Image 2: Single bank, banded, generic raster"); 
     showIt(image3, "Image 3: Multibank, banded raster"); 
     showIt(image4, "Image 4: Multibank, banded, generic raster"); 

     // Part II 
     // Now, the single array image, could also be used to create somehting more standard (the images will *NOT* look the same, despite sharing data) 

     // Create raster directly from buffer 
     int[] interleavedOffsets = createIndices(bands, bands - 1, -1); // 2, 1, 0 (BufferedImage.TYPE_3BYTE_BGR has this order) 
     WritableRaster interleavedRaster1 = Raster.createInterleavedRaster(singleBuffer, width, height, bands * width, bands, interleavedOffsets, origin); 
     System.out.println("interleavedRaster1: " + interleavedRaster1); 

     // Create raster from sample model and buffer 
     PixelInterleavedSampleModel interleavedModel = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, width, height, bands, bands * width, interleavedOffsets); 
     WritableRaster interleavedRaster2 = Raster.createWritableRaster(interleavedModel, singleBuffer, origin); 
     System.out.println("interleavedRaster2: " + interleavedRaster2); 

     // Create images for all of the raster types 
     BufferedImage image5 = new BufferedImage(colorModel, interleavedRaster1, colorModel.isAlphaPremultiplied(), null); 
     System.out.println("image5: " + image5); 
     BufferedImage image6 = new BufferedImage(colorModel, interleavedRaster2, colorModel.isAlphaPremultiplied(), null); 
     System.out.println("image6: " + image6); 

     // Uncomment these lines, to better understand the difference between banded and interleaved :-) 
//  Arrays.fill(singleData, bandSize, 2 * bandSize, (byte) 255); 
//  Arrays.fill(multiData[1], (byte) 255); 

     // And finally display to prove it works just fine 
     showIt(image5, "Image 5: Single bank, interleaved raster"); 
     showIt(image6, "Image 6: Single bank, interleaved raster"); 
    } 

    private static int[] createIndices(final int count, final int start, final int increment) { 
     int[] indices = new int[count]; 

     for (int i = 0; i < count; i++) { 
      indices[i] = start + i * increment; 
     } 

     return indices; 
    } 

    private static void showIt(final BufferedImage image, final String title) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       JFrame frame = new JFrame(title); 
       frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 
       frame.addWindowListener(new WindowAdapter() { 
        @Override public void windowClosed(final WindowEvent e) { 
         if (Window.getWindows() == null || Window.getWindows().length == 0) { 
          System.exit(0); 
         } 
        } 
       }); 
       frame.add(new JLabel(new ImageIcon(image))); 
       frame.pack(); 
       frame.setLocationByPlatform(true); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 

테스트 출력이 생겼는지 ... 인터리브 된 래스터 1 & 2가 같기 때문에해야한다고 생각합니다.