2016-04-06 4 views
4

Я хотел бы извлечь прямоугольник BufferedImage.BufferedImage: извлечение субизображения с теми же данными

Javadoc предлагает getSubImage (x, y, w, h) и getData (прямоугольник).

getData классный, но я не хочу только растра. Я хочу SubImage как объект BufferedImage, но мне также нужен модифицированная версия этого массива данных, но Javadoc говорит

общественного BufferedImage getSubimage (целое х, Int у, Int W, внутр ч): Возвращает SubImage определенной заданной прямоугольной областью. Возвращенный BufferedImage использует тот же массив данных, что и исходное изображение.

В: Как я могу извлечь субимаг с усеченным массивом данных?

+1

Извлечение суб изображение, окрашивать его сделать еще BufferedImage, изменить к вашему сердцу – MadProgrammer

+0

это computationnaly эффективным? –

+0

Я понятия не имею, это просто и работает, и вы получаете BufferedImage, который является копией дополнительного изображения, но не будет влиять на оригинал при изменении. Пойдите и сделайте некоторые из ваших собственных сравнений, чтобы проверить, что работает для вас – MadProgrammer

ответ

5

Учитывая BufferedImage образом, вот 3 способа создания «глубокого "копия SubImage:

// Create an image 
BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR); 

// Fill with static 
new Random().nextBytes(((DataBufferByte) image.getRaster().getDataBuffer()).getData()); 

Создать изображение вокруг уже глубокой копии Raster вы получаете от getData(rect). Это включает в себя листинг до WritableRaster, поэтому он может ломаться с некоторыми реализациями Java или в будущем. Должно быть довольно быстро, как вы только скопировать данные один раз:

// Get sub-raster, cast to writable and translate it to 0,0 
WritableRaster data = ((WritableRaster) image.getData(new Rectangle(25, 25, 50, 50))).createWritableTranslatedChild(0, 0); 

// Create new image with data 
BufferedImage subOne = new BufferedImage(image.getColorModel(), data, image.isAlphaPremultiplied(), null); 

Другой вариант, создание суб образа «нормальный путь», то копирование растра в новое изображение. Предполагает создание одного суб-растра, по-прежнему копирует только один раз (и не литья):

// Get subimage "normal way" 
BufferedImage subimage = image.getSubimage(25, 25, 50, 50); 

// Create empty compatible image 
BufferedImage subTwo = new BufferedImage(image.getColorModel(), image.getRaster().createCompatibleWritableRaster(50, 50), image.isAlphaPremultiplied(), null); 

// Copy data into the new, empty image 
subimage.copyData(subTwo.getRaster()); 

Наконец, проще маршрут, просто покраска SubImage над новым пустым изображением. Может быть немного медленнее, поскольку он связан с конвейером рендеринга, но я думаю, что он должен действовать достаточно спокойно.

// Get subimage "normal way" 
BufferedImage subimage = image.getSubimage(25, 25, 50, 50); 

// Create new empty image of same type 
BufferedImage subThree = new BufferedImage(50, 50, image.getType()); 

// Draw the subimage onto the new, empty copy 
Graphics2D g = subThree.createGraphics(); 
try { 
    g.drawImage(subimage, 0, 0, null); 
} 
finally { 
    g.dispose(); 
} 
+0

Благодарим за всеобъемлющий ответ! –

0

У меня была такая же проблема давным-давно, мне не нужен общий растровый. Единственное решение, которое я нашел, это создать BufferedImage, который представляет суб-изображение, а затем скопировать пиксели в суб-изображение.

Для того, чтобы иметь что-то очень быстро, я получить доступ непосредственно DataBuffer и я делаю копию массива (строка за строкой) с использованием System.arraycopy()

 Смежные вопросы

  • Нет связанных вопросов^_^