문제

현재 다음 코드를 사용하여 픽셀 값 (원래 java.awt.image.pixelgrabber 객체로 생성)을 이미지 객체로 바꾸고 있습니다.

public Image getImageFromArray(int[] pixels, int width, int height) {
    MemoryImageSource mis = new MemoryImageSource(width, height, pixels, 0, width);
    Toolkit tk = Toolkit.getDefaultToolkit();
    return tk.createImage(mis);
}

AWT 툴킷을 사용할 필요가 없으므로 ImageIO 패키지의 클래스를 사용하여 동일한 결과를 얻을 수 있습니까?

Toolkit.getDefaultToolKit ()는 100% 신뢰할 수없는 것처럼 보이며 때로는 awterror를 던지지 만 Imageio 클래스는 항상 사용할 수 있어야하므로 내 방법을 변경하는 데 관심이있는 이유입니다.

도움이 되었습니까?

해결책

imageio를 사용하지 않고 이미지를 만들 수 있습니다. 픽셀 배열의 내용과 일치하는 이미지 유형을 사용하여 BufferedImage를 만듭니다.

public static Image getImageFromArray(int[] pixels, int width, int height) {
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            WritableRaster raster = (WritableRaster) image.getData();
            raster.setPixels(0,0,width,height,pixels);
            return image;
        }

Pixelgrabber와 함께 작업 할 때 전화하기 전에 픽셀 어레이에서 RGBA 정보를 추출하는 것을 잊지 마십시오. getImageFromArray. 이것의 예가 있습니다 handlepixelmethod Pixelgrabber Javadoc에서. 이렇게하면 BufferedImage 생성자의 이미지 유형이 BufferedImage.TYPE_INT_ARGB.

다른 팁

래스터를 사용하여 나는 얻었다 ArrayIndexOutOfBoundsException 내가 만들어도 BufferedImage ~와 함께 TYPE_INT_ARGB. 그러나 사용 setRGB(...) 의 방법 BufferedImage 나를 위해 일했습니다.

javadoc on bufferedimage.getData ()는 다음과 같이 말합니다. 복사 이미지 데이터의. "

이 코드는 나에게 효과적이지만 효율성이 의심합니다.

        // Получаем картинку из массива.
        int[] pixels = new int[width*height];
            // Рисуем диагональ.
            for (int j = 0; j < height; j++) {
                for (int i = 0; i < width; i++) {
                    if (i == j) {
                        pixels[j*width + i] = Color.RED.getRGB();
                    }
                    else {
                        pixels[j*width + i] = Color.BLUE.getRGB();
                        //pixels[j*width + i] = 0x00000000;
                    }
                }
            }

BufferedImage pixelImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);    
    pixelImage.setRGB(0, 0, width, height, pixels, 0, width);

Java.awt.robot을 사용하여 스크린 샷 (또는 화면의 세그먼트)을 가져 오기 위해 성공을 거두었지만 Imageio와 함께 작동하려면 메모리 이미지 소스 대신 BufferedImage에 저장해야합니다. 그런 다음 하나의 정적 인 Imageio 메소드를 호출하고 파일을 저장할 수 있습니다. 다음과 같은 것을 시도하십시오.

// Capture whole screen
Rectangle region = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capturedImage = new Robot().createScreenCapture(region);

// Save as PNG
File imageFile = new File("capturedImage.png");
ImageIO.write(capturedImage, "png", imageFile);

이것은 SO에서 Imageio로 태그가 붙은 가장 높은 투표 질문 중 하나이므로 질문이 오래된 경우에도 더 나은 솔루션을위한 여지가 여전히 있다고 생각합니다. :-)

살펴보십시오 BufferedImageFactory.java Github의 오픈 소스 Imageio 프로젝트에서 수업.

그것으로 간단히 쓸 수 있습니다.

BufferedImage image = new BufferedImageFactory(image).getBufferedImage();

또 다른 좋은 점은이 접근법이 최악의 경우와 거의 같은 성능 (시간)을 가지고 있다는 것입니다. PixelGrabber-이 스레드에서 이미 기반 예제. 대부분의 일반적인 경우 (일반적으로 JPEG)의 경우 약 2 배 빠릅니다. 어쨌든 메모리가 적습니다.

측면 보너스로, 기본 색상 모델을 사용하여 int argb로 번역하는 대신 원본 이미지의 컬러 모델 및 픽셀 레이아웃이 유지됩니다. 추가 메모리를 절약 할 수 있습니다.

(PS : 공장은 또한 관심있는 사람이라면 서브 샘플링, 영역 및 진행 리스너도 지원합니다. :-)

이 질문의 정답을 적용하려는 다른 모든 사람들의 동일한 문제가 있었는데, 내 int 배열은 실제로 배열의 길이가 widht*height*3이어야하기 때문에 하나 더 인덱스를 추가하는 것을 수정하는 곳에서 실제로 아웃소드 바운드 렉스크를 얻습니다. 이미지를 가져올 수 없어서 래스터를 이미지로 설정했습니다.

public static Image getImageFromArray(int[] pixels, int width, int height) {
        BufferedImage image = new BufferedImage(width, height,     BufferedImage.TYPE_INT_ARGB);
        WritableRaster raster = (WritableRaster) image.getData();
        raster.setPixels(0,0,width,height,pixels);
        image.setData(raster); 
        return image;
    }

그리고 이와 같은 JFrame의 레이블에 표시되면 이미지를 볼 수 있습니다.

    JFrame frame = new JFrame();
    frame.getContentPane().setLayout(new FlowLayout());
    frame.getContentPane().add(new JLabel(new ImageIcon(image)));
    frame.pack();
    frame.setVisible(true);

imageicon ()에서 이미지 설정. 마지막 조언은 bufferedImage.type_int_argb를 다른 것으로 변경하려고 시도 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top