2009-02-12 6 views
4

У меня есть старый Java-код Java, который я хочу использовать повторно, но интересно, это лучший способ получить изображения самого высокого качества?Java 2D и resize

public static BufferedImage getScaled(BufferedImage imgSrc, Dimension dim) { 

    // This code ensures that all the pixels in the image are loaded. 
    Image scaled = imgSrc.getScaledInstance(
      dim.width, dim.height, Image.SCALE_SMOOTH); 

    // This code ensures that all the pixels in the image are loaded. 
    Image temp = new ImageIcon(scaled).getImage(); 

    // Create the buffered image. 
    BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), 
      temp.getHeight(null), BufferedImage.TYPE_INT_RGB); 

    // Copy image to buffered image. 
    Graphics g = bufferedImage.createGraphics(); 
    // Clear background and paint the image. 
    g.setColor(Color.white); 
    g.fillRect(0, 0, temp.getWidth(null),temp.getHeight(null)); 
    g.drawImage(temp, 0, 0, null); 
    g.dispose(); 


    // j2d's image scaling quality is rather poor, especially when 
    // scaling down an image to a much smaller size. We'll post filter 
    // our images using a trick found at 
    // http://blogs.cocoondev.org/mpo/archives/003584.html 
    // to increase the perceived quality.... 
    float origArea = imgSrc.getWidth() * imgSrc.getHeight(); 
    float newArea = dim.width * dim.height; 
    if (newArea <= (origArea/2.)) { 
     bufferedImage = blurImg(bufferedImage); 
    } 

    return bufferedImage; 
} 

public static BufferedImage blurImg(BufferedImage src) { 
    // soften factor - increase to increase blur strength 
    float softenFactor = 0.010f; 
    // convolution kernel (blur) 
    float[] softenArray = { 
      0,    softenFactor,  0, 
      softenFactor, 1-(softenFactor*4), softenFactor, 
      0,    softenFactor,  0}; 

    Kernel kernel = new Kernel(3, 3, softenArray); 
    ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); 
    return cOp.filter(src, null); 
} 

ответ

4

Крис Кэмпбелл имеет отличную и детальную информацию о масштабировании изображений - см. this article.

Чет Хэазе и Ромен Гай также имеют подробную и очень информативную рецензию масштабирования изображений в своей книге, Filthy Rich Clients.

+0

действительно замечательные статьи. благодаря! – Epaga

2

Вы можете использовать JAI (Java Advanced Imaging), чтобы получить более сложные параметры изменения размера изображения. См. https://jai.dev.java.net/. Это дает вам большую гибкость, чем пакет java.awt.image.

3

Добавление пояснительной информации здесь.

Нет, это не Лучшее способ получить хорошее масштабируемое изображение на Java. Использование getScaledInstance и базового AreaAveragingScaleFilter устарело командой Java2D в пользу более продвинутых методов.

Если вы просто пытаетесь получить красивую миниатюру, то, используя метод Криса Кэмпбелла, предложенный Дэвидом, это путь. Для чего это стоит, я реализовал этот алгоритм вместе с двумя другими более быстрыми методами в библиотеке масштабирования изображений Java под названием imgscalr (лицензия Apache 2). Дело библиотеки было конкретно рассмотреть этот вопрос в высоко настроенной библиотеки, которая проста в использовании:

BufferedImage thumbnail = Scalr.resize(srcImg, 150); 

Чтобы получить выглядящий лучше масштабируется экземпляр возможного в Java, вызов метода будет выглядеть следующим образом:

BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 
             150, 100, Scalr.OP_ANTIALIAS); 

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

Если вы еще не работали с convolveops, это много работы, чтобы получить идеально выглядящее ядро, чтобы op выглядел хорошо во всех случаях использования. Константа OP, определенная в классе Scalr, является результатом недели совместной работы с сайтом социальной сети в Бразилии, который развернул imgscalr для обработки изображений профиля для своих членов. Мы шли туда и обратно и пробовали что-то вроде 10 разных ядер, пока не нашли тот, который был достаточно тонким, чтобы изображение не выглядело мягким или нечетким, но все равно сглаживало переходы между значениями пикселей, чтобы изображение не выглядело «острым» и шумным при небольших размерах.

Если вы хотите, чтобы масштабируемое изображение было оптимальным, независимо от его скорости, перейдите к предложению Юхи использовать библиотеку масштабирования java-изображений. Это очень обширная коллекция Java2D Ops и включает в себя поддержку Lanczsos algorithm, которая даст вам лучший результат.

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

1

Вы можете изменить размер изображения с помощью Open Source Library enter link description here

я сделал с большими изображениями для малых и результата отличными, сохраняя соотношение сторон штрафа.

import java.awt.image.BufferedImage; 
import java.io.File; 
import javax.imageio.ImageIO; 
import javax.swing.JOptionPane; 
import org.imgscalr.*; 
import org.imgscalr.Scalr.Method; 


public class ImageScaller { 
static String SRC_FILES_PATH = "I:\\BigGreen\\"; 
static String IMAGE_FILE_PATH = "I:\\Resized\\"; 
public ImageScaller() {   
} 
public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    try 
    { 
     ResizeLoad(SRC_FILES_PATH); 
    } 
    catch(Exception ex) 
    { 
     System.out.println(ex.toString()); 
    } 
} 
public static int ResizeLoad(String path) 
{ 
    String file; 
    File folder ; 
    File[] listOfFiles = null;  
    listOfFiles = null; 
    try 
    {   
     folder = new File(path); 
     listOfFiles = folder.listFiles(); 

     for (int i = 0; i < listOfFiles.length; i++)      
     {     
      if (listOfFiles[i].isFile()) 
      { 
       file = listOfFiles[i].getName(); 
       ScalledImageWrite(listOfFiles[i].getPath(),file);         
       //System.out.println(file); 
       } 
      } 
     System.out.println("All Resized"); 
     } 

    catch (Exception e) 
     { 
      JOptionPane.showMessageDialog(null,e.toString(),"Resize & Load :Exception",JOptionPane.WARNING_MESSAGE);     
     } 
    return listOfFiles.length; 
} 
private static File ScalledImageWrite(String path,String fileName) 
    { 
     try 
     { 
      BufferedImage img = ImageIO.read(new File(path));    
      BufferedImage scaledImg = Scalr.resize(img, Method.AUTOMATIC, 24, 24);     
      File destFile = new File(IMAGE_FILE_PATH + fileName);  
      ImageIO.write(scaledImg, "png", destFile);     
      //System.out.println("Done resizing"); 
      return destFile; 
     } 
     catch (Exception e) 
     { 
      JOptionPane.showMessageDialog(null,e.toString(),"Scalled Images Write: Exception",JOptionPane.WARNING_MESSAGE); 
      return null; 
     } 
    } 

} 

Вот вывод в изобразительном формате этого кода. enter image description here