Android implements compressed local pictures
1. Project Overview
In various social, malls, photo albums and other applications, pictures often need to be compressed to reduce file size, upload traffic, and memory usage. Image compression can not only improve transmission efficiency, but also improve user experience while ensuring a certain quality.
This project aims to realize local image compression function through the Android platform, and its main goals include:
Select an image from local: With the help of the system album or file selector, let users select the pictures they need to compress;
Bitmap compression processing: Use control sampling rate to achieve quality compression through () method;
Image preview and storage: After compression, display the image on the interface and support saving the results locally;
Performance and resource management: Optimize large image processing and memory usage to avoid memory overflow and ANR;
Modular design: All codes are integrated and are explained in detail to facilitate subsequent expansion.
2. Analysis of background and related technologies
2.1 The significance and application scenarios of image compression
Save network traffic: The compressed image is smaller in size, faster upload and download speed, and reduce user traffic consumption.
Reduce server pressure: Reduced uploading image volume can save server storage space and improve processing efficiency.
Improve memory usage: When displaying large-size pictures, reduce memory usage through sampling to avoid memory overflow problems.
Improve user experience: Fast loading and smooth display are crucial to the user experience, especially in low-network environments.
2.2 Android image processing basics and Bitmap overview
Bitmap class: In Android, Bitmap is the core class that represents image data. Understanding Bitmap's memory footprint, resolution, color configuration (such as ARGB_8888 and RGB_565) is the basis for image processing.
BitmapFactory: Provides a method to load Bitmap from files, resources, and input streams, and supports setting the sampling rate (inSampleSize) to reduce image resolution through Options.
Canvas and Paint: When processing Bitmap, you usually use Canvas and Paint to achieve picture drawing and synthesis.
2.3 The role of inSampleSize
inSampleSize parameter: This is an important parameter in . By setting the value of inSampleSize, you can scale down the size of the original image. For example, setting inSampleSize = 2 reduces the image width and height by half, reducing the memory usage to a quarter of the original one.
Quality and performance balance: Reasonable setting inSampleSize can reduce memory consumption and processing time while ensuring image quality, and is suitable for large-scale upload scenarios.
2.4 () Method and picture encoding
() method: A data stream used to compress Bitmap into a specified format (such as JPEG, PNG, WEBP). By setting the compression quality (0-100), we can achieve a balance between image clarity and file volume.
Compression format selection: JPEG format is suitable for color photos, and it is smaller in volume after compression, but may cause distortion; PNG format is lossless but the file size is larger; WEBP format has both advantages, but it is only supported in some Android versions.
3. Project requirements and implementation difficulties
3.1 Project requirements description
The main requirements of this project are as follows:
-
Select a local image
Use the system album or file selector to let users select the pictures they want to upload and display a preview on the interface.
-
Image compression
Sampling and compression is performed by controlling inSampleSize;
By () the quality compression of Bitmap is supported, and formats such as JPEG, PNG, etc. users can choose to compress quality parameters.
-
Show and save results
Display the compressed image on the interface ImageView and supports saving compressed images to local storage.
-
Asynchronous background operation
Network transmission and image processing operations must be completed in the background thread to avoid blocking the main UI thread.
-
Exception and permission management
Handle memory overflow, IO exceptions and other issues; declare necessary permissions in , such as READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE.
-
Code structure and scalability
All Java and XML code are integrated to distinguish different modules through detailed annotations, ensuring clear code, easy maintenance and subsequent expansion (such as batch compression, online upload combination, etc.).
3.2 Implementing difficulties and challenges
The main difficulties and challenges include:
Large image memory management
Memory overflow is easy when loading large high-definition images, and it is necessary to sample reasonably and use inSampleSize to reduce the Bitmap size.Compression mass and file volume balance
How to reduce the size of the image file as much as possible while ensuring that the key details of the image are not distorted, it is necessary to set appropriate compression formats and quality parameters.Asynchronous and multi-threaded processing
Image compression and saving operations are long and must be processed asynchronously in the background thread, while ensuring that the UI can correctly update the processing results.Save and share mechanism
After the compression is completed, the image will be saved locally or the sharing function is provided, and file reading and writing, path management and compatibility issues need to be handled.
4. Design ideas and overall architecture
4.1 Overall design ideas
This project uses Bitmap operation and Canvas drawing to achieve image compression. The main design ideas are as follows:
Image selection and loading
Get the image URI selected by the user through the system album selector (Intent.ACTION_PICK), use on-demand settings inSampleSize to sample and load Bitmap to reduce memory usage.-
Picture compression module
Write the ImageCompressionUtils tool class, providing two compression methods:Use inSampleSize to adjust the resolution to achieve sampling and compression effect;
Call the () method to perform quality compression of Bitmap, support JPEG, PNG, and WEBP formats, and set compression quality parameters.
Save and share module
Save the compressed Bitmap to the local file system, write data using FileOutputStream, and share the image through Intent.UI and interactive modules
The main activity provides image preview, compression parameter adjustment (such as compression ratio, quality) and upload/share buttons to display the compression effect feedback to users in real time.Background and asynchronous operations
Image compression and file saving operations are executed in the background thread using AsyncTask (or other asynchronous programming methods) to ensure smooth UI.
4.2 Module division and logical structure
The main modules of the project are divided into the following parts:
-
Image selection and loading module
Calling through the system album allows the user to select images and use the original Bitmap to load.
-
Picture compression tool module ()
Provides static methods compressImageBySampling() and compressImageByQuality() to realize sampling compression and quality compression functions respectively.
-
Save and share module
Provides a method to save Bitmap to a file, and supports calling system sharing functions.
-
UI and Active Modules
MainActivity displays image preview, compression parameter settings, compression execution and result display, and calls the image compression tool module.
-
Layout and resource management modules
Integrate all XML layout files (main Activity layout, buttons, and preview areas), color, string, and style resources to distinguish sections with detailed comments.
5. Complete code implementation
The complete code example is provided below, where all Java and XML code are integrated and separate different modules with detailed comments. In this example, the ImageCompressionUtils tool class is used to implement image compression function, and MainActivity is responsible for image selection, display and invoking compression methods.
5.1 Java code implementation
// =========================================== // document:// Description: Picture compression tool class, providing two methods based on sampling rate and quality compression// =========================================== package ; import ; import ; import ; import ; import ; public class ImageCompressionUtils { /** * Use setting inSampleSize to achieve sampling and compression * @param filePath Local path to image file * @param reqWidth expect width * @param reqHeight Expected height * @return Sample compressed Bitmap */ public static Bitmap compressImageBySampling(String filePath, int reqWidth, int reqHeight) { // The first read setting inJustDecodeBounds is true Only the image size is obtained final options = new (); = true; (filePath, options); // Calculate the inSampleSize value = calculateInSampleSize(options, reqWidth, reqHeight); // The second read setting inJustDecodeBounds gets the actual Bitmap for false = false; return (filePath, options); } /** * Calculate a reasonable inSampleSize based on the original image size and target size */ public static int calculateInSampleSize( options, int reqWidth, int reqHeight) { // Original image width and height final int height = ; final int width = ; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // Calculate the aspect ratio final int halfHeight = height / 2; final int halfWidth = width / 2; // Ensure that the width and height after compression are still greater than the target width and height while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } } return inSampleSize; } /** * Use () method to achieve quality compression * @param bitmap Original Bitmap * @param format compression format (JPEG, PNG, WEBP) * @param quality Compression quality (0-100, 100 is the highest quality) * @return Compressed Bitmap */ public static Bitmap compressImageByQuality(Bitmap bitmap, format, int quality) { if (bitmap == null) return null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); (format, quality, baos); byte[] data = (); return (data, 0, ); } /** * Save Bitmap as a file * @param bitmap Bitmap to be saved * @param destFile Save the target file * @param format Save format * @param quality Save quality * @return true Save successfully, false Save failed */ public static boolean saveBitmapToFile(Bitmap bitmap, File destFile, format, int quality) { if (bitmap == null || destFile == null) { return false; } FileOutputStream fos = null; try { fos = new FileOutputStream(destFile); (format, quality, fos); (); return true; } catch (Exception e) { (); return false; } finally { if (fos != null) { try { (); } catch (Exception ex) { } } } } } // =========================================== // document:// Description: Sample Activity, showing how to select local pictures, perform compression previews, and save compression results// =========================================== package ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; public class MainActivity extends AppCompatActivity { private static final int REQUEST_CODE_SELECT_IMAGE = 100; private ImageView ivOriginal; private ImageView ivCompressed; private Button btnCompress; private Uri selectedImageUri; private Bitmap originalBitmap; @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); // Set layout file activity_main.xml setContentView(.activity_main); ivOriginal = findViewById(.iv_original); ivCompressed = findViewById(.iv_compressed); btnCompress = findViewById(.btn_compress); // Click the original image area to select the picture (new () { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_PICK, .EXTERNAL_CONTENT_URI); startActivityForResult(intent, REQUEST_CODE_SELECT_IMAGE); } }); // Click the compression button to perform picture compression, use the quality compression method to use the example (new () { @Override public void onClick(View v) { if(originalBitmap != null) { //Asynchronous tasks perform compression operations to prevent blocking the main thread new CompressImageTask().execute(); } else { (, "Please select a picture first", Toast.LENGTH_SHORT).show(); } } }); // Check storage read permissions if ((this, .READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { (this, new String[] { .READ_EXTERNAL_STORAGE }, 1); } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { (requestCode, resultCode, data); if(requestCode == REQUEST_CODE_SELECT_IMAGE && resultCode == RESULT_OK && data != null) { selectedImageUri = (); try { // Load preview Bitmap InputStream inputStream = getContentResolver().openInputStream(selectedImageUri); originalBitmap = (inputStream); (originalBitmap); } catch (Exception e) { (); } } } /** * CompressImageTask asynchronous task, perform image compression operations in the background */ private class CompressImageTask extends AsyncTask<Void, Void, Bitmap> { @Override protected void onPreExecute() { (, "Start compressing pictures", Toast.LENGTH_SHORT).show(); } @Override protected Bitmap doInBackground(Void... voids) { // Example: Sample compression first, then mass compression String imagePath = (, selectedImageUri); //Resolution is reduced by sampling (e.g. target size 800x800) Bitmap sampledBitmap = (imagePath, 800, 800); // Then perform quality compression and set the compression quality of JPEG format and 70 return (sampledBitmap, , 70); } @Override protected void onPostExecute(Bitmap compressedBitmap) { if(compressedBitmap != null) { (compressedBitmap); // Save the compressed picture to the local area (save directory and file name customization) File dir = getExternalFilesDir("CompressedImages"); if(dir != null && !()) { (); } File outFile = new File(dir, () + ".jpg"); boolean success = (compressedBitmap, outFile, , 70); if(success) { (, "Compressed image saved successfully:" + (), Toast.LENGTH_LONG).show(); } else { (, "Compressed image saving failed", Toast.LENGTH_SHORT).show(); } } else { (, "Image compression failed", Toast.LENGTH_SHORT).show(); } } } } // =========================================== // document:// Description: Tool class, get the actual file path from the picture URI, adapting to different Android versions// =========================================== package ; import ; import ; import ; import ; public class PathUtil { public static String getRealPathFromURI(Context context, Uri contentUri) { String[] proj = { }; Cursor cursor = ().query(contentUri, proj, null, null, null); if(cursor != null){ int column_index = (); (); String path = (column_index); (); return path; } return null; } }
5.2 XML resource file implementation
<!-- =========================================== document: activity_main.xml describe: MainActivity 的布局document,Contains original image preview、Compressed image preview and upload buttons =========================================== --> <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:andro android: android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:padding="16dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center_horizontal"> <TextView android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click the image below to select the original image" android:textSize="18sp" android:layout_marginBottom="8dp"/> <ImageView android: android:layout_width="300dp" android:layout_height="300dp" android:background="#EEEEEE" android:scaleType="centerCrop" android:layout_marginBottom="16dp" android:contentDescription="Original Image Preview"/> <Button android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Compressed Pictures" android:layout_marginBottom="16dp"/> <TextView android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Compressed image preview" android:textSize="18sp" android:layout_marginBottom="8dp"/> <ImageView android: android:layout_width="300dp" android:layout_height="300dp" android:background="#EEEEEE" android:scaleType="centerCrop" android:contentDescription="Compressed image preview"/> </LinearLayout> </ScrollView> <!-- =========================================== document: describe: Define the color resources used in the project =========================================== --> <?xml version="1.0" encoding="utf-8"?> <resources> <color name="white">#FFFFFF</color> <color name="primary">#3F51B5</color> </resources> <!-- =========================================== document: describe: Define application themes and style resources,use AppCompat theme =========================================== --> <?xml version="1.0" encoding="utf-8"?> <resources> <style name="AppTheme" parent=""> <item name="android:windowBackground">@color/white</item> <item name="android:textColorPrimary">@color/primary</item> </style> </resources>
6. Code interpretation and detailed explanation
6.1 Picture sampling and memory control
Use
In (), first, the original size of the picture is read by setting inJustDecodeBounds, and then the appropriate inSampleSize value is calculated to achieve proportional sampling and loading of the picture and reduce memory usage.Combination of sampling and mass compression
By first sampling compression, reducing the resolution, and then calling () for quality compression, the image volume can be greatly reduced while maintaining a good visual effect.
6.2 () Method and parameter description
Compression format and quality
Using the () method, you can select JPEG, PNG or WEBP formats and set the compression quality (0~100) through the quality parameter;Memory and performance considerations
Combining the inSampleSize and compress() methods can not only reduce image memory usage, but also speed up file upload and display speed, balancing quality and performance.
6.3 Asynchronous tasks and UI updates
AsyncTask Application
In MainActivity, image compression operations are performed in child threads through the UploadTask asynchronous task, and the compression results are updated in onPostExecute() and displayed in ImageView. Files can be saved or shared.Path resolution and file saving
Use the PathUtil tool class to get the actual file path from the picture URI, and use the () method to save the compressed Bitmap to the specified directory.
7. Performance optimization and debugging skills
7.1 Memory Management and Bitmap Reuse
sampling
When loading large images, use sampling technology to reduce image resolution, reduce memory usage, and avoid OOM;Object reuse
Try to reuse objects such as Paint, ByteArrayOutputStream and other objects during image compression to reduce frequent creation and garbage collection.
7.2 Asynchronous tasks and thread optimization
Background execution
Time-consuming operations such as image compression are performed in AsyncTask or other asynchronous methods to ensure smooth UI main thread;Network and IO performance
If uploading is involved in subsequently, it is recommended to combine OkHttp and Retrofit to achieve efficient network communication.
7.3 Log debugging and exception capture
Log output
Add log debugging information in key steps (such as image loading, compression, and file saving) to facilitate the use of Logcat to analyze problems;Exception handling
Add a try-catch mechanism to Bitmap operations and file IO to ensure timely feedback when abnormalities are caused by memory, permissions and other issues.
8. Project Summary and Future Outlook
8.1 Project Summary
This project introduces in detail how to implement the compression function of local images in Android applications, including sampling compression and quality compression. The main achievements include:
-
Image loading and sampling technology
By calculating inSampleSize, image sampling and loading is realized and memory usage is reduced;
-
Quality compression implementation
Using the () method, compress Bitmap into JPEG (or other format), and customize the compression quality parameters to achieve a balance between file size and image quality;
-
Asynchronous tasks and results display
Use AsyncTask to process image compression, avoid time-consuming operations in UI threads, and display results in real time through ImageView;
-
Modular code structure
Modularly encapsulate functions such as image selection, compression processing, file saving, etc. in independent tool classes, and all codes are integrated together, with a clear structure for subsequent expansion.
8.2 Future expansion and optimization directions
In the future, we can further expand and optimize this project in the following aspects:
-
Batch image compression
Extended to support multi-image batch processing, and realize compression progress display and queue management;
-
More efficient asynchronous processing
Use RxJava, Kotlin Coroutine or WorkManager to schedule background tasks to improve code responsiveness;
-
Dynamically adjust compression parameters
Provides an interface that allows users to customize sampling rate, compression format and quality parameters, and preview compression effects in real time;
-
Combined with image upload
Integrate image compression and upload functions to reduce the uploaded file volume and improve network transmission efficiency;
-
Quality inspection and optimization
Combined with image processing algorithms, automatically detect the compressed image quality, adjust the compression strategy, and take into account both visual effects and file size;
-
Exception and error handling
Build a complete error capture and retry mechanism, give detailed feedback and automatic retry when image processing or file storage fails.
The above is the detailed content of Android's ability to compress local pictures. For more information about Android's compressed local pictures, please follow my other related articles!
Related Articles
Android implements custom gorgeous water ripple effect
Regarding the water ripples effect of Android, the editor has shared with you a few similar articles. If you are interested, you can check it out through the relevant articles below. Today, I will share with you a gorgeous water ripples effect. This effect is very good. If you are interested, you can refer to it.2016-08-08Implementation of video progress bars encapsulated by Android Flutter control
This article mainly shares a very simple controller packaging case with you, including basic playback pause, full screen and exit full screen. The sample code in the article is explained in detail. If you are interested, you can learn about it.2023-06-06Example of transition animation of Android 5.0
This article mainly introduces an example of the transition animation of Activity in Android 5.0. It is very practical. Friends who need it can refer to it.2017-10-10Tutorial on the installation and use of genymotion on Android emulator
This article mainly introduces the installation and use of genymotion in detail to you. It has certain reference value. Interested friends can refer to it.2016-08-08Summary of common Android programming skills examples
This article mainly introduces a summary of common Android programming techniques, including Android dialog boxes, resolutions, resources, fonts and other operating techniques. It has certain reference value. Friends who need it can refer to it.2015-11-11Android uses GridView to implement simple functions of calendar
This article mainly introduces in detail the simple function of Android using GridView to implement calendars, which has certain reference value. Interested friends can refer to it.2016-12-12Android rewrites View and customizes attribute instance analysis
This article mainly introduces the method of Android rewriting View and customizing properties. Combined with the example form, it analyzes the relevant layout and specific techniques of Android to implement custom properties based on rewriting View. Friends who need it can refer to it.2016-02-02Implementation and comparison of three onClicks in Android
This article mainly introduces the implementation methods of three onClick in Android and the detailed comparison. The sample code in the article is explained in detail. Interested friends can follow the editor to learn it.2025-04-04Android custom control implements a universal verification code input box
This article mainly introduces the Android custom controls to implement a universal verification code input box. The sample code in the article is introduced in detail and has a certain reference value. Interested friends can refer to it.2021-01-01Detailed explanation of the usage of HTTP services in Android
This article mainly introduces a detailed explanation of the usage of HTTP services in Android. If you need it, you can learn about it.2016-11-11