Pregunta

Soy un programador Java razonablemente experimentado pero relativamente nuevo en Java2d. Estoy tratando de escalar una imagen, pero obtengo resultados de baja calidad. La imagen es una vista previa de un panel, por lo que contiene cosas como texto y campos de texto. Siempre estaré escalando, nunca levantaré.

Actualmente estoy usando el siguiente código:-

g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null);

Donde PanelImage es la vista previa de tamaño completo (BufferedImage) y ScaledWidth y ScaledHeight son las dimensiones objetivo respectivas. Parece que pierdo muchos detalles en el texto y los bordes de cosas como los campos de texto, etc.

¿Hay una mejor llamada que debería usar para escalar la imagen?

Gracias John

¿Fue útil?

Solución

Una sugerencia que puedo hacer es cambiar el tamaño primero de la imagen en un BufferedImage. La razón es, un Graphics2D objeto de la BufferedImage se puede obtener para producir una imagen a escala de mejor calidad.

Graphics2D puede aceptar "presentaciones de representación" que instruyen la forma en que el procesamiento de imágenes debe ser realizado por el Graphics2D objeto. los setRenderingHint El método es uno de los métodos que se pueden utilizar para establecer las pistas de representación. La representación de sugerencias del RenderingHints La clase se puede usar.

Entonces, usando eso Graphics2D objeto, se puede dibujar una imagen al BufferedImage Usando las sugerencias de renderización especificadas anteriormente.

Un código áspero (no probado) funcionaría como el siguiente:

BufferedImage scaledImage = new BufferedImage(
    scaledWidth,
    scaledHeight,
    BufferedImage.TYPE_INT_RGB
);

Graphics2D g = scaledImage.createGraphics();
g.setRenderingHints(
    RenderingHints.Key.KEY_INTERPOLATION,
    RenderingHints.VALUE_INTERPOLATION_BICUBIC
);

g.drawImage(panelImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();

Otros indicios de interés pueden incluir:

los Control de calidad de representación La sección de los tutoriales de Java también tiene más información sobre cómo controlar la calidad de representación de Graphics2D objetos.

Y para una muy buena fuente de información sobre cómo tratar con interfaces gráficas en general, Clientes ricos Por Chet Haase y Romain Guy es muy recomendable. Hay una sección del libro que se ocupa del tema de la escala de imágenes, que parece bastante relevante.

Otros consejos

Puede ser que debas llamar:

 g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

y

g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

Coobird tiene razón en que necesita a escala descendente incrementalmente (preferiblemente usando bicubic) para obtener un resultado atractivo para una miniatura lo suficientemente pequeña. Image.getScaledInstance solía hacer esto con el enfoque del área_averaged, pero es mucho más lento que el descendente incremental que fue original propuesto por Chris Campbell en su artículo "Peligros de imagen. GetScaledInstance ()".

Disculpe la autopromoción aquí, pero puse un puñado de "mejores prácticas nativas de Java" cuando se trata de escalar imágenes en una biblioteca llamada imgscalr.

Está disponible bajo una licencia de Apache 2 y la fuente está todo en GitHub; El objetivo de la biblioteca era hacer escala de imágenes en Java Native Dead-Easy (1 clase, 5 Métodos estáticos) y garantizar el resultado más atractivo (que es lo que originalmente quería), el resultado más rápido (excelente al escalar entre imágenes grandes ) o un equilibrio entre los dos y deje que la biblioteca decida cuál usar.

Solo quería una lib que pudiera "cambiar el tamaño de mi imagen y salir de mi camino" y después de leer todas estas publicaciones durante unos días mientras abordaba el punto de dolor (el mío también) simplemente estaba dando vueltas y compartiendo el trabajo para cualquiera de lo contrario puede ayudar.

Coobird tiene la idea correcta. Yo tambien lo intentaría RenderingHints.VALUE_INTERPOLATION_BILINEAR interpolación y ver si es más agradable. Sin embargo, el bicúbico funciona mejor cuando se escala. Para obtener los mejores resultados al reducir la escala, uno debería Desense en varios pasos. Primero reduzca a la mitad la resolución, luego reduzca a la mitad nuevamente, etc. hasta que se acerque a la resolución deseada (es decir, no puede reducir a la mitad o la imagen se volverá demasiado pequeña). El paso final es reducir a la resolución deseada.

Por ejemplo, digamos que su imagen de entrada es 800x600 Y quieres que se redactara a 160x120:

  1. Enonjado 50%. --> 400x300
  2. Enonjado 50%. --> 200x150
  3. Ausente 160x120.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top