una tamaño redimensionar poner pequeña mas imagen hacer como centrar boton ampliar ajustar java image resize

redimensionar - Cambiar el tamaño de la imagen manteniendo la relación de aspecto en Java



poner imagen en jlabel java (6)

Estoy intentando cambiar el tamaño de bufferdImage en la memoria en java pero para mantener la relación de aspecto de la imagen. Tengo algo como esto, pero esto no es bueno.

int w = picture.getWidth(); int h = picture.getWidth(); int neww=w; int newh=h; int wfactor = w; int hfactor = h; if(w > DEFULT_PICTURE_WIDTH || h > DEFULT_PICTURE_HIGHT) { while(neww > DEFULT_PICTURE_WIDTH) { neww = wfactor /2; newh = hfactor /2; wfactor = neww; hfactor = newh; } } picture = Utils.resizePicture(picture,neww,newh);


Agregando al punto de Erik sobre getScaledInstance, si se alejó de él para usar los mecanismos de escala recomendados en Java2D, es posible que haya notado que sus imágenes se ven notablemente peores.

La razón de esto es que cuando Java2D desalentó el uso de getScaledInstance y AreaAveragingScaleFilter, no lo reemplazaron con nada tan fácil de usar en la API, en lugar de eso, nos dejaron a nuestros propios dispositivos utilizando las API de Java2D directamente. Afortunadamente, Chris Campbell (del equipo J2D) siguió con la recomendación de usar una técnica de escalamiento incremental que da resultados de aspecto similar a AreaAveragingScaleFilter y corre más rápido; desafortunadamente, el código es de un tamaño decente y no aborda su pregunta original de honrar proporciones.

Hace aproximadamente 6 meses vi todas estas preguntas en SO una y otra vez sobre "escalar imágenes en Java" y, finalmente, reuní todos los consejos, hice todas las investigaciones e investigaciones que pude, y compilé todo en una sola escala de imagen de "mejores prácticas" biblioteca

La API es muy simple, ya que es solo una clase y un montón de métodos estáticos. El uso básico se ve así:

BufferedImage img = ImageIO.read(...); // load image BufferedImage scaledImg = Scalr.resize(img, 320);

Esta es la llamada más simple en la que la biblioteca hará una mejor estimación de la calidad, respetará las proporciones de la imagen y ajustará el resultado dentro de un cuadro delimitador de 320x320. NOTA, el cuadro delimitador es solo el W / H máximo utilizado, ya que se respetan las proporciones de la imagen, la imagen resultante aún lo respeta, por ejemplo, 320x200.

Si desea anular el modo automático y forzarlo para obtener el mejor resultado e incluso aplicar un filtro anti-alias muy suave al resultado para que se vea aún mejor (especialmente bueno para las miniaturas), esa llamada se vería así:

BufferedImage img = ImageIO.read(...); // load image BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 150, 100, Scalr.OP_ANTIALIAS);

Estos son solo ejemplos, la API es amplia y cubre todo, desde casos de uso súper simples hasta muy especializados. Incluso puede pasar su propio BufferedImageOps para que se aplique a la imagen (¡y la biblioteca soluciona automáticamente el error de 6 años de BufferedImageOp JDK para usted!)

La biblioteca hace mucho más que escalar con éxito las cosas que la biblioteca hace por usted, por ejemplo, siempre manteniendo la imagen en uno de los mejores tipos de imagen RGB o ARGB compatibles mientras opera en ella. Bajo las coberturas, el proceso de procesamiento de imágenes de Java2D se reduce a un programa de software inferior si el tipo de imagen utilizado para cualquier operación de imagen no es compatible.

Si todo eso suena como un gran dolor de cabeza, es como ... es por eso que escribí la biblioteca y la abrí, así que la gente podría simplemente cambiar el tamaño de sus imágenes y seguir adelante con sus vidas sin tener que preocuparse por eso.

Espero que ayude.


Para empezar, eche un vistazo a la línea 2. ¿No debería ser getHeight() ?

No desea un bucle while para el cambio de tamaño, desea averiguar la relación de cambio de tamaño, que es un poco de matemáticas.

(width / height) = (new_width / new_height)

Si conoce uno de los tamaños ''nuevos'', el otro se puede encontrar a través de la multiplicación

new_height * (width / height) = new_width

También puede usar el método perezoso proporcionado por BufferedImage''s imagen de BufferedImage''s superclase BufferedImage''s , getScaledInstance() : usar -1 para el ancho o el alto mantendrá la relación de aspecto

ex:
scaledPic = picture.getScaledInstance(new_width, -1, Image.SCALE_FAST);


Puede echar un vistazo a perils-of-image-getscaledinstance.html que explica por qué debe getScaledInstance() , que se usa en algunas de las respuestas.

El artículo también proporciona código alternativo.


Si desea cambiar el tamaño de una imagen de w0 x h0 a w1 x h1 manteniendo la relación de aspecto, calcule la escala vertical y horizontal y seleccione la más pequeña.

double scalex = 1; double scaley = 1; if (scalingMode == ScalingMode.WINDOW_SIZE) { scalex = (double)getWidth() / frontbuffer.getWidth(); scaley = (double)getHeight() / frontbuffer.getHeight(); } else if (scalingMode == ScalingMode.KEEP_ASPECT) { double sx = (double)getWidth() / frontbuffer.getWidth(); double sy = (double)getHeight() / frontbuffer.getHeight(); scalex = Math.min(sx, sy); scaley = scalex; // center the image g2.translate((getWidth() - (frontbuffer.getWidth() * scalex)) / 2, (getHeight() - (frontbuffer.getHeight() * scaley)) / 2); } g2.scale(scalex, scaley); if (interpolation != ImageInterpolation.NONE) { g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolation.hint); } g2.drawImage(frontbuffer, 0, 0, null);


Si se conoce el ancho, la altura de la fuente y el destino, use la siguiente función para determinar la escala de la imagen.

private double determineImageScale(int sourceWidth, int sourceHeight, int targetWidth, int targetHeight) { double scalex = (double) targetWidth / sourceWidth; double scaley = (double) targetHeight / sourceHeight; return Math.min(scalex, scaley);

}

Luego use esta escala para escalar hacia arriba / abajo la imagen usando el siguiente código

Image scaledImage = sourceBufferedImage.getScaledInstance((int) (width * scale), (int) (height * scale), Image.SCALE_SMOOTH);


Utilizo estos dos métodos para escalar imágenes, donde max es la dimensión más grande de su imagen de destino. Para imágenes de 100x100 será 100, para imágenes de 200x300 será 300.

public static BufferedImage scale(InputStream is, int max) { Image image = null; try { image = ImageIO.read(is); } catch (IOException e) { e.printStackTrace(); } int width = image.getWidth(null); int height = image.getHeight(null); double dWidth = 0; double dHeight = 0; if (width == height) { dWidth = max; dHeight = max; } else if (width > height) { dWidth = max; dHeight = ((double) height / (double) width) * max; } else { dHeight = max; dWidth = ((double) width / (double) height) * max; } image = image.getScaledInstance((int) dWidth, (int) dHeight, Image.SCALE_SMOOTH); BufferedImage bImage = toBufferedImage(image); return bImage; } public static BufferedImage toBufferedImage(Image img) { if (img instanceof BufferedImage) { return (BufferedImage) img; } BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); Graphics2D bGr = bimage.createGraphics(); bGr.drawImage(img, 0, 0, null); bGr.dispose(); return bimage; }