English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Este ejemplo comparte con ustedes el código específico de la herramienta de compresión de imágenes android, a fin de que lo puedan referenciar, el contenido específico es el siguiente
import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.graphics.Matrix; import android.net.Uri; import android.widget.Toast; /** * Clase de herramienta para imágenes circulares * * @author SKLM * */ public class ImageViewTool { /** * Veamos primero el método de compresión de calidad * * @param image * @return */ public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// método de compresión de calidad, aquí100 significa no comprimir, y guardar los datos comprimidos en baos int options = 100; while (baos.toByteArray().length / 1024 > 100) { // revisa en el ciclo si la imagen comprimida es mayor que100kb, mayor continuar comprimiendo baos.reset();// restablecer baos es equivalente a vaciar baos image.compress(Bitmap.CompressFormat.JPEG, options, baos);// aquí comprimo options%, y guardo los datos comprimidos en baos options -= 10;// cada vez que se reduce10 } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// Almacenar los datos comprimidos de baos en ByteArrayInputStream Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// Generar una imagen a partir de los datos de ByteArrayInputStream return bitmap; } /** * Método de compresión de tamaño proporcional de la imagen (obteniendo la imagen según la ruta y comprimiendo) * * @param srcPath * @return */ public static Bitmap getimage(String srcPath) { BitmapFactory.Options newOpts = new BitmapFactory.Options(); // Comience a leer la imagen, en este momento establezca options.inJustDecodeBounds en true newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// En este momento, el bm devuelto está vacío newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; // Now most mainstream mobile phones are800*480 resolution, so we set both height and width to float hh = 800f;// here we set the height to800f float ww = 480f;// here we set the width to480f // Relación de escala. Debido a que es una escala de proporción fija, solo se puede calcular con uno de los datos de altura o ancho int be = 1;// be=1Representa no escalar if (w > h && w > ww) {// Si el ancho es grande, ajuste el tamaño según el ancho fijo be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {// Si la altura es alta, ajuste el tamaño según el ancho fijo be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;// Establecer la proporción de escala // Vuelva a leer la imagen, preste atención de que en este momento ya ha establecido options.inJustDecodeBounds en false bitmap = BitmapFactory.decodeFile(srcPath, newOpts); return compressImage(bitmap);// Comprime el tamaño proporcional primero y luego comprime por calidad } /** * Método de compresión de tamaño proporcional de la imagen (basado en la compresión de Bitmap) * * @param image * @return */ public static Bitmap comp(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos); if (baos.toByteArray().length / 1024 > 1024) {// juzgar si la imagen es mayor que1M, realizar la compresión para evitar que se sobrecargue al generar la imagen (BitmapFactory.decodeStream) baos.reset();// restablecer baos es equivalente a vaciar baos image.compress(Bitmap.CompressFormat.JPEG, 30, baos);// Aquí se comprime50%,almacenar los datos comprimidos en baos } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); BitmapFactory.Options newOpts = new BitmapFactory.Options(); // Comience a leer la imagen, en este momento establezca options.inJustDecodeBounds en true newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; // Now most mainstream mobile phones are800*480 resolution, so we set both height and width to float hh = 150f;// here we set the height to800f float ww = 150f;// here we set the width to480f // Relación de escala. Debido a que es una escala de proporción fija, solo se puede calcular con uno de los datos de altura o ancho int be = 1;// be=1Representa no escalar if (w > h && w > ww) {// Si el ancho es grande, ajuste el tamaño según el ancho fijo be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {// Si la altura es alta, ajuste el tamaño según el ancho fijo be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;// Establecer la proporción de escala // Vuelva a leer la imagen, preste atención de que en este momento ya ha establecido options.inJustDecodeBounds en false isBm = new ByteArrayInputStream(baos.toByteArray()); bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); return compressImage(bitmap);// Comprime el tamaño proporcional primero y luego comprime por calidad } public static byte[] Bitmap2Bytes(Bitmap bm) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG, 100, baos); return baos.toByteArray(); } /** * compress the image to the specified size in original proportion * * @param context * @param inputUri * @param outputUri * @param maxLenth * longestSideLength */ public static void reducePicture(Context context, Uri inputUri, Uri outputUri, int maxLenth, int compress) { Options options = new Options(); options.inJustDecodeBounds = true; InputStream is = null; try { is = context.getContentResolver().openInputStream(inputUri); BitmapFactory.decodeStream(is, null, options); is.close(); int sampleSize = 1; int longestSide = 0; int longestSideLenth = 0; if (options.outWidth > options.outHeight) { longestSideLenth = options.outWidth; longestSide = 0; } else { longestSideLenth = options.outHeight; longestSide = 1; } if (longestSideLenth > maxLenth) { sampleSize = longestSideLenth / maxLenth; } options.inJustDecodeBounds = false; options.inSampleSize = sampleSize; is = context.getContentResolver().openInputStream(inputUri); Bitmap bitmap = BitmapFactory.decodeStream(is, null, options); is.close(); if (bitmap == null) { Toast.makeText(context, "Fallo en la obtención de la imagen, por favor asegúrese de que su tarjeta de almacenamiento esté en buen estado", Toast.LENGTH_SHORT).show(); return; } Bitmap srcBitmap = bitmap; float scale = 0; if (longestSide == 0) { scale = (float) maxLenth / (float) (srcBitmap.getWidth()); } else { scale = (float) maxLenth / (float) (srcBitmap.getHeight()); } Matrix matrix = new Matrix(); matrix.postScale(scale, scale); bitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true); // Si el tamaño no cambia, se devolverá el propio objeto, por lo que se necesita determinar si es una referencia común para determinar si es necesario reciclar if (srcBitmap != bitmap) { srcBitmap.recycle(); srcBitmap = null; } saveBitmapToUri(bitmap, outputUri, compress); bitmap.recycle(); bitmap = null; } catch (FileNotFoundException e) { // TODO Auto-generado bloque de captura e.printStackTrace(); } catch (IOException e) { // TODO Auto-generado bloque de captura e.printStackTrace(); } } private static boolean saveBitmapToUri(Bitmap bitmap, Uri uri, int compress) throws IOException { File file = new File(uri.getPath()); if (file.exists()) { if (file.delete()) { if (!file.createNewFile()) { return false; } } } BufferedOutputStream outStream = new BufferedOutputStream( new FileOutputStream(file)); bitmap.compress(Bitmap.CompressFormat.JPEG, compress, outStream); outStream.flush(); outStream.close(); return true; } }
Veamos ahora el segundo enfoque para la clase de herramienta de compresión de imágenes, como se muestra a continuación
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.sql.Date; import java.text.SimpleDateFormat; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.os.Environment; /** * Clase fábrica de compresión de imágenes * * @author * */ public class ImageFactory { /** * Obtener bitmap desde la ruta de imagen especificada * * @param imgPath * @return */ public Bitmap getBitmap(String imgPath) { // Obtener bitmap a través de la ruta de la imagen BitmapFactory.Options newOpts = new BitmapFactory.Options(); newOpts.inJustDecodeBounds = false; newOpts.inPurgeable = true; newOpts.inInputShareable = true; // No comprimir newOpts.inSampleSize = 1; newOpts.inPreferredConfig = Config.RGB_565; return BitmapFactory.decodeFile(imgPath, newOpts); } /** * comprimir imagen (compresión de calidad) * * @param bitmap */ public static File compressImage(Bitmap bitmap) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);// método de compresión de calidad, aquí100 significa no comprimir, y guardar los datos comprimidos en baos int options = 100; while (baos.toByteArray().length / 1024 > 500) { // revisa en el ciclo si la imagen comprimida es mayor que500kb, mayor continúa comprimiendo baos.reset();// restablecer baos es equivalente a vaciar baos options -= 10;// cada vez que se reduce10 bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);// aquí comprimo options%, y guardo los datos comprimidos en baos long length = baos.toByteArray().length; } SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); Date date = new Date(System.currentTimeMillis()); String filename = format.format(date); File file = new File(Environment.getExternalStorageDirectory(), filename + ".png"); try { FileOutputStream fos = new FileOutputStream(file); try { fos.write(baos.toByteArray()); fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } recycleBitmap(bitmap); return file; } public static void recycleBitmap(Bitmap... bitmaps) { if (bitmaps == null) { return; } for (Bitmap bm : bitmaps) { if (null != bm && !bm.isRecycled()) { bm.recycle(); } } } /** * almacenar el bitmap en la ruta de imagen especificada * * @param bitmap * @param outPath * @throws FileNotFoundException */ public void storeImage(Bitmap bitmap, String outPath) throws FileNotFoundException { FileOutputStream os = new FileOutputStream(outPath); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os); } /** * comprimir la imagen a través de los píxeles, lo que cambiará el ancho de la imagen/altura. Utilizado para obtener la vista previa * * * @param imgPath * ruta de la imagen * @param pixelW * Anchura en píxeles objetivo * @param pixelH * Altura en píxeles objetivo * @return */ public Bitmap ratio(String imgPath, float pixelW, float pixelH) { BitmapFactory.Options newOpts = new BitmapFactory.Options(); // comenzar a leer la imagen, en este momento se ha restablecido options.inJustDecodeBounds a true, es decir, solo leer los bordes y no el contenido newOpts.inJustDecodeBounds = true; newOpts.inPreferredConfig = Config.RGB_565; // Obtener información de la bitmap, pero prestar atención a que la bitmap es null ahora Bitmap bitmap = BitmapFactory.decodeFile(imgPath, newOpts); newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; // el tamaño objetivo que se desea escalar float hh = pixelH;// Establecer la altura a240f, se puede ver claramente que la imagen se ha reducido float ww = pixelW;// Establecer el ancho a120f, se puede ver claramente que la imagen se ha reducido // Relación de escala. Debido a que es una escala de proporción fija, solo se puede calcular con uno de los datos de altura o ancho int be = 1;// be=1Representa no escalar if (w > h && w > ww) {// Si el ancho es grande, ajuste el tamaño según el ancho fijo be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {// Si la altura es alta, ajuste el tamaño según el ancho fijo be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;// Establecer la proporción de escala // comenzar a comprimir la imagen, prestando atención a que en este momento se ha restablecido options.inJustDecodeBounds a false bitmap = BitmapFactory.decodeFile(imgPath, newOpts); // Comprime el tamaño proporcional primero y luego comprime por calidad // return compress(bitmap, maxSize); // No tiene mucho sentido comprimir de nuevo por calidad aquí, consume recursos, eliminar return bitmap; } /** * comprimir el tamaño de la imagen, lo que modificará el ancho de la imagen/altura. Utilizado para obtener la vista previa * * * @param image * @param pixelW * píxel objetivo de anchura * @param pixelH * píxel objetivo de altura * @return */ public Bitmap ratio(Bitmap image, float pixelW, float pixelH) { ByteArrayOutputStream os = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, os); if (os.toByteArray().length / 1024 > 1024) {// juzgar si la imagen es mayor que1M, realizar la compresión para evitar que se sobrecargue al generar la imagen (BitmapFactory.decodeStream) os.reset();// restablecer baos es equivalente a vaciar baos image.compress(Bitmap.CompressFormat.JPEG, 50, os);// Aquí se comprime50%,almacenar los datos comprimidos en baos } ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); BitmapFactory.Options newOpts = new BitmapFactory.Options(); // Comience a leer la imagen, en este momento establezca options.inJustDecodeBounds en true newOpts.inJustDecodeBounds = true; newOpts.inPreferredConfig = Config.RGB_565; Bitmap bitmap = BitmapFactory.decodeStream(is, null, newOpts); newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; float hh = pixelH;// Establecer la altura a240f, se puede ver claramente que la imagen se ha reducido float ww = pixelW;// Establecer el ancho a120f, se puede ver claramente que la imagen se ha reducido // Relación de escala. Debido a que es una escala de proporción fija, solo se puede calcular con uno de los datos de altura o ancho int be = 1;// be=1Representa no escalar if (w > h && w > ww) {// Si el ancho es grande, ajuste el tamaño según el ancho fijo be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {// Si la altura es alta, ajuste el tamaño según el ancho fijo be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;// Establecer la proporción de escala // Vuelva a leer la imagen, preste atención de que en este momento ya ha establecido options.inJustDecodeBounds en false is = new ByteArrayInputStream(os.toByteArray()); bitmap = BitmapFactory.decodeStream(is, null, newOpts); // Comprime el tamaño proporcional primero y luego comprime por calidad // return compress(bitmap, maxSize); // No tiene mucho sentido comprimir de nuevo por calidad aquí, consume recursos, eliminar return bitmap; } /** * Comprime por calidad y genera la imagen en la ruta especificada * * @param image * @param outPath * @param maxSize * El objetivo será comprimido a un tamaño menor que este (KB). * @throws IOException */ public void compressAndGenImage(Bitmap image, String outPath, int maxSize) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); // escala int options = 100; // Almacenar el bitmap en el flujo de salida (sin comprimir) image.compress(Bitmap.CompressFormat.JPEG, options, os); // Comprimir en bucle while (os.toByteArray().length / 1024 > maxSize) { // Limpiar os os.reset(); // interval 10 options -= 10; image.compress(Bitmap.CompressFormat.JPEG, options, os); } // Generar archivo de imagen comprimida FileOutputStream fos = new FileOutputStream(outPath); fos.write(os.toByteArray()); fos.flush(); fos.close(); } /** * Comprime por calidad y genera la imagen en la ruta especificada * * @param imgPath * @param outPath * @param maxSize * El objetivo será comprimido a un tamaño menor que este (KB). * @param needsDelete * ¿Desea comprimir y eliminar el archivo original? * @throws IOException */ public void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException { compressAndGenImage(getBitmap(imgPath), outPath, maxSize); // Eliminar archivo original if (needsDelete) { File file = new File(imgPath); if (file.exists()) { file.delete(); } } } /** * Especificar la ruta de proporción y generación de miniaturas * * @param image * @param outPath * @param pixelW * Anchura en píxeles objetivo * @param pixelH * Altura en píxeles objetivo * @throws FileNotFoundException */ public void ratioAndGenThumb(Bitmap image, String outPath, float pixelW, float pixelH) throws FileNotFoundException { Bitmap bitmap = ratio(image, pixelW, pixelH); storeImage(bitmap, outPath); } /** * Especificar la ruta de proporción y generación de miniaturas * * @param image * @param outPath * @param pixelW * Anchura en píxeles objetivo * @param pixelH * Altura en píxeles objetivo * @param needsDelete * ¿Desea comprimir y eliminar el archivo original? * @throws FileNotFoundException */ public void ratioAndGenThumb(String imgPath, String outPath, float pixelW, float pixelH, boolean needsDelete) throws FileNotFoundException { Bitmap bitmap = ratio(imgPath, pixelW, pixelH); storeImage(bitmap, outPath); // Eliminar archivo original if (needsDelete) { File file = new File(imgPath); if (file.exists()) { file.delete(); } } } }
Esto es todo el contenido del artículo, espero que ayude a su aprendizaje y que todos lo apoyen a gritar tutorial.
Declaración: El contenido de este artículo se obtiene de la red, es propiedad del autor original, el contenido se contribuye y carga de manera autónoma por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha realizado una edición humana y no asume ninguna responsabilidad legal. Si encuentra contenido sospechoso de infracción de derechos de autor, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, reemplace # con @ para denunciar y proporcione evidencia. Una vez confirmado, este sitio eliminará inmediatamente el contenido sospechoso de infracción de derechos de autor.)