-
Notifications
You must be signed in to change notification settings - Fork 0
/
BitmapUtility.java
153 lines (137 loc) · 6.64 KB
/
BitmapUtility.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
* Copyright 2019 Kaushik N. Sanji
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.kaushiknsanji.xploremysuru.utils;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.support.v7.graphics.Palette;
import android.text.TextUtils;
/**
* Utility class that deals with reading, extracting information and modifying {@link android.graphics.Bitmap}.
*
* @author Kaushik N Sanji
*/
public class BitmapUtility {
//Constant used when no Resource Id is found for a Drawable
public static final int NO_RESOURCE_ID = 0;
//Constant for the Resource Directory name
private static final String RESOURCE_DIR_NAME = "res";
//Definition Type constant for Drawable
private static final String TYPE_DRAWABLE_RES = "drawable";
/**
* Private Constructor to avoid direct instantiation of {@link BitmapUtility}
*/
private BitmapUtility() {
//Suppressing with an error to enforce noninstantiability
throw new AssertionError("No " + this.getClass().getCanonicalName() + " instances for you!");
}
/**
* Method that extracts a Vibrant or a Dark Vibrant Palette Swatch from the {@code bitmap}
* given.
* <p>
* This method needs to be invoked from a background thread.
* </p>
*
* @param bitmap The {@link Bitmap} of an Image from which the Vibrant Palette Swatch needs to
* be extracted.
* @return A Vibrant or a Dark Vibrant {@link Palette.Swatch} for the given {@link Bitmap}.
* If Vibrant is not available then the Dark Vibrant will be returned. Can be {@code null}
* if the Dark Vibrant is also not available or when the {@link Bitmap} given is {@code null}.
*/
@Nullable
@WorkerThread
public static Palette.Swatch extractVibrantSwatch(@Nullable Bitmap bitmap) {
//Returning NULL when the Bitmap is NULL
if (bitmap == null) {
return null;
}
//Generating the Palette for the Bitmap
Palette palette = Palette.from(bitmap).generate();
//Reading the Vibrant Swatch
Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
if (vibrantSwatch == null) {
//When Vibrant is not available, pick the Dark Vibrant
vibrantSwatch = palette.getDarkVibrantSwatch();
}
//Return the Vibrant/Dark-Vibrant Swatch extracted
return vibrantSwatch;
}
/**
* Method that finds the Resource Id of the Drawable given the Resource Path {@code resourcePath}
* to the Drawable present in resources.
*
* @param resourcePath The Resource Path String to the Drawable whose Resource Id is to be found
* @param packageName The Package Name of the App
* @param resources Instance of {@link Resources}
* @return The Resource Id of the Drawable resource if found or {@link #NO_RESOURCE_ID} when not found.
* When {@code resourcePath} is invalid, {@link #NO_RESOURCE_ID} will be returned.
*/
@DrawableRes
public static int findDrawableResourceId(String resourcePath, String packageName, Resources resources) {
if (!TextUtils.isEmpty(resourcePath) && resourcePath.startsWith(RESOURCE_DIR_NAME)) {
//When Resource Path is present and points to the Resources directory of the App
//Determining the start and end for extracting the Resource Name from the Path
int startIndex = resourcePath.lastIndexOf("/");
int endIndex = resourcePath.lastIndexOf(".");
//Returning the Resource Id found for the Resource Path passed
return resources.getIdentifier(
resourcePath.substring(startIndex + 1, endIndex), //The Resource Name
TYPE_DRAWABLE_RES, //The 'res' type
packageName //The Package Name of the App
);
}
//Returning '0' when the Resource Path was invalid
return NO_RESOURCE_ID;
}
/**
* Method that decodes and returns an Optimized {@link Bitmap} from the Drawable Resource pointed to by
* the Resource Id {@code imageResourceId}.
* <p>
* This method needs to be invoked from a background thread.
* </p>
*
* @param context A {@link Context} to read the Window dimensions
* @param resources Instance of {@link Resources}
* @param imageResourceId The Resource Id of the Drawable to be decoded.
* @return An Optimized {@link Bitmap} decoded from the Drawable Resource {@code imageResourceId}
*/
@WorkerThread
public static Bitmap getOptimizedBitmapFromResource(Context context, Resources resources, @DrawableRes int imageResourceId) {
//Get the device target dimensions (Normalizing to 50 percent of the value)
int targetW = (int) (WindowDimensionsUtility.getDisplayWindowWidth(context) * 0.5);
int targetH = (int) (WindowDimensionsUtility.getDisplayWindowHeight(context) * 0.5);
//Creating an Instance of BitmapFactory Options to decode the dimensions of the original
//Bitmap from the Image Resource
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = true; //Decoding for Bounds only
//Decoding the dimensions of the original bitmap
BitmapFactory.decodeResource(resources, imageResourceId, bitmapOptions);
//Reading the bitmap's original dimensions
int photoW = bitmapOptions.outWidth;
int photoH = bitmapOptions.outHeight;
//Calculating the amount to scale down the image
int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
//Decode the image using the scaling factor determined
bitmapOptions.inJustDecodeBounds = false; //Decoding the Image
bitmapOptions.inSampleSize = scaleFactor;
//Decoding into Bitmap with the scaled down dimensions and returning the same
return BitmapFactory.decodeResource(resources, imageResourceId, bitmapOptions);
}
}