2012-03-20 2 views
3

У меня есть несколько изображений, и каждое изображение имеет разрешение около 2560x10000, я хочу объединить все эти изображения, чтобы сделать одно изображение. Я не могу использовать метод BufferedImage в качестве конечного изображения, и изображение, которое я должен объединить, будет в памяти, одновременно вызывая OutOfMemory. Поэтому я попробовал использовать нижеприведенный подход:объединить несколько изображений jpeg с низкой или постоянной площадью памяти

public static void joinJpegFiles(File infile, File outfile, float compQuality,int i) { 
    try { 
     RenderedImage renderedImage = ImageIO.read(infile); 
     ImageWriter Iwriter = null; 

     Iterator iter = ImageIO.getImageWritersByFormatName("jpeg"); 
     if (iter.hasNext()) { 
      Iwriter = (ImageWriter)iter.next(); 
     } 

     ImageOutputStream IOStream = ImageIO.createImageOutputStream(outfile); 
     Iwriter.setOutput(IOStream); 
     IOStream.seek(IOStream.length()); 
     JPEGImageWriteParam JIWP=new JPEGImageWriteParam(Locale.getDefault()); 
     JIWP.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ; 
     JIWP.setCompressionQuality(compQuality); 
     Iwriter.write(null, new IIOImage(renderedImage,null,null), JIWP);    
     IOStream.flush(); 
     IOStream.close(); 
     Iwriter.dispose(); 
    } catch (IOException e) { 
     System.out.println("write error: " + e.getMessage()); 
    } 
} 

Этот метод предназначен для каждого изображения, к которому я хочу присоединиться.
Проблема с этим подходом заключается в том, что размер конечного изображения увеличивается и равен сумме размеров всех изображений, к которым я присоединился, но только первое изображение отображается, когда я открываю конечное изображение. Я все еще не могу понять, что я делаю неправильно, и я также не смог найти какой-либо пример кода, чтобы присоединиться к jpegs, кроме подхода BufferedImage и ImageIO.write. Я читал в группе новостей, что он работает для формата tiff, но мне нужно, чтобы он работал в форматах jpeg/png.

+0

FYI Я также использовал ** Iwriter.write (-1, новый IIOImage (renderedImage, null, null), JIWP); ** но это вызывает исключение Unsupported Exception. – barry

+0

Вы когда-нибудь решали это? – mwoodman

+0

немного поздно, но я сделал это с помощью [JMagick] (http://sourceforge.net/apps/mediawiki/jmagick/index.php?title=Main_Page), любой, у кого есть эта проблема, должен хотя бы дать ему попробовать , – JosephChilberry

ответ

1

Я предполагаю, что вы уже решили эту проблему, или работал вокруг него как-то, но .. В случае, если кто-либо другой необходимости решить подобную проблему:

Это немного неясно, что вы пытаетесь достичь здесь. Вы действительно хотите создать одно большое изображение или создать один файл, содержащий несколько изображений?

Несколько изображений в одном файле:

Ваш код, кажется, чтобы добавить несколько автономных файлов JPEG в один файл. Формат JPEG (JFIF) не поддерживает это, и большинство программ, вероятно, просто видят ваш файл в качестве первого JPEG с добавлением к нему загруженных барахлов. PNG не позволяет хранить несколько изображений в одном файле AFAIK. Формат, такой как TIFF, позволяет использовать несколько изображений (даже позволяет хранить их в виде потоков JPEG), что, вероятно, связано с тем, что TIFF был поднят.

Однако стандарт JPEG имеет концепцию Abbreviated Streams, что очень похоже на то, как JPEG обычно хранится в пирамидальном TIFF. ImageIO JPEGImageWriter поддерживает эту функцию:

«Сокращенные потоки записываются с использованием методов последовательности метаданных потока ImageWriter используются для записи в таблицы только для изображения в начале потока, и таблицы настроены. для использования с использованием ImageWriter.prepareWriteSequence.Если метаданные потока не передаются в ImageWriter.prepareWriteSequence, тогда не записывается только изображение в виде таблицы. Если метаданные потока, не содержащие таблиц, передаются в ImageWriter.prepareWriteSequence, тогда изображение только для таблиц, написаны столы без потерь ».

Я не знаю, как другие программы будут интерпретировать эти типы файлов, и в соответствии с the libjpeg docs, вероятно, не будет даже работать:

«В то время как сокращенные потоки данных могут быть полезны в замкнутой окружающая среда, их использование настоятельно не рекомендуется в в любой ситуации, когда может потребоваться обмен данными с другими приложениями. Дизайнер Caveat. "

Так что оно может быть или не быть подходящим для вашего прецедента.

Compose несколько изображений в одно большое изображение:

Если с другой стороны, вы действительно хотите, чтобы составить несколько изображений в одно большое изображение (а затем хранить их в одном формате JPEG), вы могли бы посмотреть на some code Я писал давно, чтобы разрешить работу с большими изображениями без использования памяти кучи.

Он использует memory-mapped byte buffers и может быть очень медленным, если у вас недостаточно памяти для хранения данных в ОЗУ. Кроме того, итоговый BufferedImage всегда будет TYPE_CUSTOM, поэтому он будет пропускать большинство потенциально аппаратного или собственного ускорения, от которого вам обычно выгоду, и некоторые операции могут не сработать на нем. Однако, по крайней мере, вы не ограничены размером кучи и физической оперативной памятью.

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