2009-11-01 4 views
0

Приложение меня читает в довольно больших изображений (JPEG), но нужно работать только с небольшими изображениями, так что я субсемплировать их с чем-то вродеПодвыборка изображения при чтении с использованием Jai

ImageReadParam param = reader.getDefaultReadParam(); 
param.setSourceSubsampling(4, 4, 0, 0); 
img = reader.read(0); 

Однако, из-за ошибки в читатель jpeg, который не обрабатывает некоторые метаданные, которые я возвращаю другим методам, один использует JAI для чтения изображения, а затем изменяет размер (код ниже, а не я должен использовать отражение, поскольку в некоторых средах развертывания нет JAI Я знаю, что я мог бы создать вокруг этого лучше, но так оно и есть).

try { 
Class<?> c = ImageUtil.class.getClassLoader().loadClass("javax.media.jai.JAI"); 

if (c != null) { 
    URL url = new URL("file://" + file.getAbsolutePath()); 
    Method m = c.getMethod("create", String.class, Object.class); 
    Object pi = m.invoke(null, "url", url); 
    img = (BufferedImage) pi.getClass().getMethod("getAsBufferedImage").invoke(pi); 
} 
} catch (Throwable tt) { 
// ... 
} 

Однако некоторые изображения действительно большой сейчас и снова я получаю из исключений памяти, есть в любом случае я могу получить JAI, чтобы субсемплировать изображение, когда оно читается в порядке, я прочитал изображения, используя ImageReader?

ответ

0

Я предполагаю, что исключение из памяти бросается, когда вы пытаетесь сделать преобразование в BufferedImage?

Если это так, то, возможно, рассматривая возможность прикрепления к RenderedOp, возвращаемого методом создания JAI, и вместо этого использовать ParameterBlock и еще один JAI-файл для создания масштабированного изображения?

ParameterBlock paramBlock = new ParameterBlock(); 
paramBlock.addSource(((RenderedOp) pi).createInstance()); // Updated this 
paramBlock.add(0.5f); // x Scale (Change these two Scale values!) 
paramBlock.add(0.5f); // y Scale 
paramBlock.add(0.0f); // x Translate 
paramBlock.add(0.0f); // y Translate 
paramBlock.add(new InterpolationBilinear()); // I think this Interpolation should work...) 
RenderedOp resized = JAI.create("scale", paramBlock, null); 

Приведенный выше код полностью не протестирован в качестве стандарта. Я боюсь, но вам нужно начать!

После того, как вы изменили размер RenderedOp, вы должны быть в состоянии безопасно преобразовать его в BufferedImage, если вам нужно.

+0

Я пытался что-то подобное, используя «SubsampleAverage», но получил ту же ошибку, как я получил, когда я попробовал ваш, т.е. Вызванные: java.lang.IllegalArgumentException: операция «Масштаб» требует 1 исходного объекта (s). \t на javax.media.jai.JAI.createNS (JAI.java:1091) \t в javax.media.jai.JAI.create (JAI.java:977) \t в javax.media.jai.JAI.create (JAI.java:1412) \t ... 31 – vickirk

+0

Из чего я могу разобраться, источник должен быть PlanarImage, это правильно? Если я попробую вызвать getRendering(), он (очевидно) выкинет исключение из памяти :-( – vickirk

+0

Ах, это так. Объект pi, который вы получаете от вызова первого создания, должен быть RenderedOp, если вы вызываете createInstance() который должен возвращать PlanarImage, с которым вы можете работать. – Jasoon

2
RenderedOp rop = JAI.create("fileload", file.getAbsolutePath()); 

ParameterBlock pb = new ParameterBlock(); 
pb.addSource(rop); 
pb.add(0.5f); 
pb.add(0.5f); 
rop = JAI.create("scale", pb); 

// For better looking results, but slower: 
// rop = JAI.create("SubsampleAverage", pb); 

BufferedImage bufImg = rop.getAsBufferedImage();