English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Dieser Artikel teilt Ihnen die spezifische Code-Beispielklasse für die Android-Bildkomprimierung mit und dient zur Referenz. Der Inhalt ist wie folgt:
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; /** * Werkzeugklasse für runde Bilder * * @author SKLM * */ public class ImageViewTool { /** * Zunächst schauen wir uns die Methode der Qualitätskomprimierung an * * @param image * @return */ public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// Qualitätskomprimierungsmethode, hier100 bedeutet keine Komprimierung, und die komprimierten Daten werden in baos gespeichert int options = 100; while (baos.toByteArray().length / 1024 > 100) { // Schleife prüfen, ob das Bild nach dem Komprimieren größer ist als100kb, größer als fortsetzen baos.reset();// 重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, options, baos);// hier wird options% komprimiert, und die komprimierten Daten werden in baos gespeichert options -= 10;// jedes Mal wird reduziert10 } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// Speichern Sie die komprimierten Daten baos in ByteArrayInputStream Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// Erstellen Sie ein Bild aus den Daten von ByteArrayInputStream return bitmap; } /** * Bildergröße proportional komprimieren (basierend auf dem Pfad des Bildes und Komprimierung) * * @param srcPath * @return */ public static Bitmap getimage(String srcPath) { BitmapFactory.Options newOpts = new BitmapFactory.Options(); // Beginne das Lesen des Bildes, setze options.inJustDecodeBounds auf true zurück newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// In diesem Moment ist bm leer newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 float hh = 800f;// 这里设置高度为800f float ww = 480f;// 这里设置宽度为480f // Verhältnis der Skalierung. Da es sich um eine Skalierung in festem Verhältnis handelt, genügt es, nur eine der beiden Werte Höhe oder Breite zu verwenden int be = 1;// be=1Stellt eine nicht-skalierte Größe dar if (w > h && w > ww) {// Wenn die Breite groß ist, skalieren Sie basierend auf der Breite auf eine feste Größe be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {// Wenn die Höhe hoch ist, skalieren Sie basierend auf der Breite auf eine feste Größe be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;// Einstellen der Skalierung // Neu das Bild neu einlesen, beachte, dass options.inJustDecodeBounds auf false zurückgesetzt wurde; bitmap = BitmapFactory.decodeFile(srcPath, newOpts); return compressImage(bitmap);// Komprimiere die Größenverhältnisse und komprimiere dann nach Qualität } /** * Bildergröße proportional komprimieren (basierend auf Bitmap-Bildkomprimierung) * * @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) {// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出 baos.reset();// 重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, 30, baos);// Hier wird komprimiert50%, speichere die komprimierten Daten in baos } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); BitmapFactory.Options newOpts = new BitmapFactory.Options(); // Beginne das Lesen des Bildes, setze options.inJustDecodeBounds auf true zurück newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 float hh = 150f;// 这里设置高度为800f float ww = 150f;// 这里设置宽度为480f // Verhältnis der Skalierung. Da es sich um eine Skalierung in festem Verhältnis handelt, genügt es, nur eine der beiden Werte Höhe oder Breite zu verwenden int be = 1;// be=1Stellt eine nicht-skalierte Größe dar if (w > h && w > ww) {// Wenn die Breite groß ist, skalieren Sie basierend auf der Breite auf eine feste Größe be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {// Wenn die Höhe hoch ist, skalieren Sie basierend auf der Breite auf eine feste Größe be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;// Einstellen der Skalierung // Neu das Bild neu einlesen, beachte, dass options.inJustDecodeBounds auf false zurückgesetzt wurde; isBm = new ByteArrayInputStream(baos.toByteArray()); bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); return compressImage(bitmap);// Komprimiere die Größenverhältnisse und komprimiere dann nach Qualität } public static byte[] Bitmap2Bytes(Bitmap bm) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG, 100, baos); return baos.toByteArray(); } /** * 按原比例压缩图片到指定尺寸 * * @param context * @param inputUri * @param outputUri * @param maxLenth * 最长边长 */ 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, "Bildabfrage fehlgeschlagen, bitte stellen Sie sicher, dass Ihre Speicherkarte ordnungsgemäß funktioniert", 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); // Wenn die Größe nicht geändert wird, wird das Original zurückgegeben, daher muss überprüft werden, ob es sich um eine identische Referenz handelt, um zu bestimmen, ob ein Recycler erforderlich ist if (srcBitmap != bitmap) { srcBitmap.recycle(); srcBitmap = null; } saveBitmapToUri(bitmap, outputUri, compress); bitmap.recycle(); bitmap = null; } catch (FileNotFoundException e) { // TODO Auto-generierter catch Block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generierter catch Block 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; } }
Next, let's take a look at the second writing style of the image compression utility class, as follows
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; /** * Image compression factory class * * @author * */ public class ImageFactory { /** * From the specified image path to obtain the bitmap * * @param imgPath * @return */ public Bitmap getBitmap(String imgPath) { // Get bitmap through image path BitmapFactory.Options newOpts = new BitmapFactory.Options(); newOpts.inJustDecodeBounds = false; newOpts.inPurgeable = true; newOpts.inInputShareable = true; // Do not compress newOpts.inSampleSize = 1; newOpts.inPreferredConfig = Config.RGB_565; return BitmapFactory.decodeFile(imgPath, newOpts); } /** * Bild komprimieren (Qualitätskomprimierung) * * @param bitmap */ public static File compressImage(Bitmap bitmap) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);// Qualitätskomprimierungsmethode, hier100 bedeutet keine Komprimierung, und die komprimierten Daten werden in baos gespeichert int options = 100; while (baos.toByteArray().length / 1024 > 500) { // Schleife prüfen, ob das Bild nach dem Komprimieren größer ist als500kb, größer als fortzusetzen baos.reset();// 重置baos即清空baos options -= 10;// jedes Mal wird reduziert10 bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);// hier wird options% komprimiert, und die komprimierten Daten werden in baos gespeichert 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(); } } } /** * 将位图存储到指定的图像路径中 * * @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); } /** * 通过像素压缩图像,这将改变图像的宽度/高度。用于获取缩略图 * * * @param imgPath * image path * @param pixelW * 目标宽度像素 * @param pixelH * 目标高度像素 * @return */ public Bitmap ratio(String imgPath, float pixelW, float pixelH) { BitmapFactory.Options newOpts = new BitmapFactory.Options(); // 开始读入图片,此时把options.inJustDecodeBounds 设回true,即只读边不读内容 newOpts.inJustDecodeBounds = true; newOpts.inPreferredConfig = Config.RGB_565; // Get bitmap info, but notice that bitmap is null now Bitmap bitmap = BitmapFactory.decodeFile(imgPath, newOpts); newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; // 想要缩放的目标尺寸 float hh = pixelH;// Die Höhe einstellen auf240f, so kann man deutlich erkennen, dass das Bild verkleinert wurde float ww = pixelW;// Die Breite einstellen auf120f, so kann man deutlich erkennen, dass das Bild verkleinert wurde // Verhältnis der Skalierung. Da es sich um eine Skalierung in festem Verhältnis handelt, genügt es, nur eine der beiden Werte Höhe oder Breite zu verwenden int be = 1;// be=1Stellt eine nicht-skalierte Größe dar if (w > h && w > ww) {// Wenn die Breite groß ist, skalieren Sie basierend auf der Breite auf eine feste Größe be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {// Wenn die Höhe hoch ist, skalieren Sie basierend auf der Breite auf eine feste Größe be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;// Einstellen der Skalierung // 开始压缩图片,注意此时已经把options.inJustDecodeBounds 设回false了 bitmap = BitmapFactory.decodeFile(imgPath, newOpts); // Komprimiere die Größenverhältnisse und komprimiere dann nach Qualität // return compress(bitmap, maxSize); // Der weitere Qualitätskomprimierung hier hat keine große Bedeutung, im Gegenteil, sie verbraucht Ressourcen, löschen return bitmap; } /** * 压缩图像的大小,这将修改图像宽度/高度。用于获取缩略图 * * * @param image * @param pixelW * target pixel of width * @param pixelH * target pixel of height * @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) {// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出 os.reset();// 重置baos即清空baos image.compress(Bitmap.CompressFormat.JPEG, 50, os);// Hier wird komprimiert50%, speichere die komprimierten Daten in baos } ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); BitmapFactory.Options newOpts = new BitmapFactory.Options(); // Beginne das Lesen des Bildes, setze options.inJustDecodeBounds auf true zurück 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;// Die Höhe einstellen auf240f, so kann man deutlich erkennen, dass das Bild verkleinert wurde float ww = pixelW;// Die Breite einstellen auf120f, so kann man deutlich erkennen, dass das Bild verkleinert wurde // Verhältnis der Skalierung. Da es sich um eine Skalierung in festem Verhältnis handelt, genügt es, nur eine der beiden Werte Höhe oder Breite zu verwenden int be = 1;// be=1Stellt eine nicht-skalierte Größe dar if (w > h && w > ww) {// Wenn die Breite groß ist, skalieren Sie basierend auf der Breite auf eine feste Größe be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {// Wenn die Höhe hoch ist, skalieren Sie basierend auf der Breite auf eine feste Größe be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;// Einstellen der Skalierung // Neu das Bild neu einlesen, beachte, dass options.inJustDecodeBounds auf false zurückgesetzt wurde; is = new ByteArrayInputStream(os.toByteArray()); bitmap = BitmapFactory.decodeStream(is, null, newOpts); // Komprimiere die Größenverhältnisse und komprimiere dann nach Qualität // return compress(bitmap, maxSize); // Der weitere Qualitätskomprimierung hier hat keine große Bedeutung, im Gegenteil, sie verbraucht Ressourcen, löschen return bitmap; } /** * Komprimiere nach Qualität und generiere das Bild im angegebenen Pfad * * @param image * @param outPath * @param maxSize * Das Ziel wird komprimiert, bis es kleiner als diese Größe ist (KB). * @throws IOException */ public void compressAndGenImage(Bitmap image, String outPath, int maxSize) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); // scale int options = 100; // Speichere das Bitmap in den Ausgabestrom (ohne Komprimierung) image.compress(Bitmap.CompressFormat.JPEG, options, os); // Komprimiere durch Schleife while (os.toByteArray().length / 1024 > maxSize) { // Bereinige os os.reset(); // interval 10 options -= 10; image.compress(Bitmap.CompressFormat.JPEG, options, os); } // Erstelle komprimierte Bilddatei FileOutputStream fos = new FileOutputStream(outPath); fos.write(os.toByteArray()); fos.flush(); fos.close(); } /** * Komprimiere nach Qualität und generiere das Bild im angegebenen Pfad * * @param imgPath * @param outPath * @param maxSize * Das Ziel wird komprimiert, bis es kleiner als diese Größe ist (KB). * @param needsDelete * 是否压缩后删除原始文件 * @throws IOException */ public void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException { compressAndGenImage(getBitmap(imgPath), outPath, maxSize); // 删除原始文件 if (needsDelete) { File file = new File(imgPath); if (file.exists()) { file.delete(); } } } /** * 指定比例和生成缩略图的路径 * * @param image * @param outPath * @param pixelW * 目标宽度像素 * @param pixelH * 目标高度像素 * @throws FileNotFoundException */ public void ratioAndGenThumb(Bitmap image, String outPath, float pixelW, float pixelH) throws FileNotFoundException { Bitmap bitmap = ratio(image, pixelW, pixelH); storeImage(bitmap, outPath); } /** * 指定比例和生成缩略图的路径 * * @param image * @param outPath * @param pixelW * 目标宽度像素 * @param pixelH * 目标高度像素 * @param needsDelete * 是否压缩后删除原始文件 * @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); // 删除原始文件 if (needsDelete) { File file = new File(imgPath); if (file.exists()) { file.delete(); } } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
声明:本文内容来源于网络,版权归原作者所有。内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#oldtoolbag.com(在发邮件时,请将#更换为@进行举报,并提供相关证据。一经查实,本站将立刻删除涉嫌侵权内容。)