├── .gitignore ├── .idea ├── caches │ └── build_file_checksums.ser ├── codeStyles │ └── Project.xml ├── dictionaries │ └── CRC.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── ColorMatrixColorFilter.gif ├── LightingColorFilter.gif ├── PoterDuffColorFilter.gif ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── xishuang │ │ └── imageviewprocess │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── encrypt_测试.txt │ │ └── testkey.dat │ ├── java │ │ └── com │ │ │ └── xishuang │ │ │ └── imageviewprocess │ │ │ ├── algorithm │ │ │ ├── SobelAlgorithm.java │ │ │ └── SpecialColorMatrix.java │ │ │ ├── security │ │ │ ├── DecryptUtil.java │ │ │ ├── RSA.java │ │ │ └── SignKey.java │ │ │ ├── ui │ │ │ ├── ColorMatrixActivity.java │ │ │ ├── LightingActivity.java │ │ │ ├── MainActivity.java │ │ │ └── PorterDuffActivity.java │ │ │ └── util │ │ │ └── ImageUtil.java │ └── res │ │ ├── drawable-xhdpi │ │ └── bg5.jpg │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_color_matrix.xml │ │ ├── activity_lighting.xml │ │ ├── activity_main_colorfilter.xml │ │ ├── activity_porter_duff.xml │ │ └── activity_porter_duff_item.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── xishuang │ └── imageviewprocess │ └── ExampleUnitTest.java ├── appkey └── testkey.keystore ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lib_security ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── xishuang │ └── crc │ └── lib_security │ ├── MainEntry.java │ ├── ui │ ├── DecryptContainer.java │ └── EncryptContainer.java │ └── util │ ├── AES.java │ ├── Base64.java │ ├── RSA.java │ └── SignKey.java ├── settings.gradle └── testkey.keystore /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rchaocai/ImageViewProcess/7c564965a468cd23bce146f995772836f1addba8/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/dictionaries/CRC.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ColorMatrixColorFilter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rchaocai/ImageViewProcess/7c564965a468cd23bce146f995772836f1addba8/ColorMatrixColorFilter.gif -------------------------------------------------------------------------------- /LightingColorFilter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rchaocai/ImageViewProcess/7c564965a468cd23bce146f995772836f1addba8/LightingColorFilter.gif -------------------------------------------------------------------------------- /PoterDuffColorFilter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rchaocai/ImageViewProcess/7c564965a468cd23bce146f995772836f1addba8/PoterDuffColorFilter.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ImageViewProcess 2 | ImageView进行图像处理的基础功能实现 3 | 4 | ## 1、LightingColorFilter模式: 5 | mul和add像素进行图片处理 6 | 7 | ![image](https://github.com/JieYuShi/ImageViewProcess/blob/master/LightingColorFilter.gif) 8 | 9 | ## 2、PoterDuffColorFilter模式: 10 | 源颜色和PoterDuff.Mode组合使用 11 | 12 | ![image](https://github.com/JieYuShi/ImageViewProcess/blob/master/PoterDuffColorFilter.gif) 13 | 14 | ## 3、ColorMatrixColorFilter模式: 15 | 三种模式中最为自由的一种,可分别调整色调、饱和度、亮度,还能通过ColorMatrix实现单独特殊效果 16 | 17 | ![image](https://github.com/JieYuShi/ImageViewProcess/blob/master/ColorMatrixColorFilter.gif) 18 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.3" 6 | defaultConfig { 7 | applicationId "com.xishuang.imageviewprocess" 8 | minSdkVersion 15 9 | targetSdkVersion 23 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | 15 | signingConfigs { 16 | release { 17 | storeFile file("..\\appkey\\testkey.keystore") 18 | keyAlias "key0" 19 | keyPassword "123456" 20 | storePassword "123456" 21 | } 22 | debug { 23 | storeFile file("..\\appkey\\testkey.keystore") 24 | keyAlias "key0" 25 | keyPassword "123456" 26 | storePassword "123456" 27 | } 28 | } 29 | 30 | buildTypes { 31 | release { 32 | minifyEnabled false 33 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 34 | } 35 | } 36 | } 37 | 38 | dependencies { 39 | compile fileTree(include: ['*.jar'], dir: 'libs') 40 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 41 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 42 | exclude group: 'com.android.support', module: 'support-annotations' 43 | }) 44 | compile 'com.android.support:appcompat-v7:23.0.0' 45 | compile 'com.android.support:recyclerview-v7:23.0.0' 46 | } 47 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/xishuang/imageviewprocess/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.xishuang.imageviewprocess", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 23 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/assets/encrypt_测试.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rchaocai/ImageViewProcess/7c564965a468cd23bce146f995772836f1addba8/app/src/main/assets/encrypt_测试.txt -------------------------------------------------------------------------------- /app/src/main/assets/testkey.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rchaocai/ImageViewProcess/7c564965a468cd23bce146f995772836f1addba8/app/src/main/assets/testkey.dat -------------------------------------------------------------------------------- /app/src/main/java/com/xishuang/imageviewprocess/algorithm/SobelAlgorithm.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess.algorithm; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.ColorMatrix; 7 | import android.graphics.ColorMatrixColorFilter; 8 | import android.graphics.Matrix; 9 | import android.graphics.Paint; 10 | 11 | /** 12 | * Author : xishuang 13 | * Date : 2018.04.02 14 | * Desc : Sobel边缘检测算法 15 | */ 16 | public class SobelAlgorithm { 17 | /** 18 | * Sobel算法 19 | */ 20 | public static Bitmap Sobel(Bitmap bitmap) { 21 | 22 | bitmap = compress(bitmap, 480, 800); 23 | Bitmap temp = toGrayscale(bitmap); 24 | int w = temp.getWidth(); 25 | int h = temp.getHeight(); 26 | 27 | int[] mmap = new int[w * h]; 28 | double[] tmap = new double[w * h]; 29 | int[] cmap = new int[w * h]; 30 | 31 | temp.getPixels(mmap, 0, temp.getWidth(), 0, 0, temp.getWidth(), 32 | temp.getHeight()); 33 | 34 | double max = Double.MIN_VALUE; 35 | for (int i = 0; i < w; i++) { 36 | for (int j = 0; j < h; j++) { 37 | double gx = GX(i, j, temp); 38 | double gy = GY(i, j, temp); 39 | tmap[j * w + i] = Math.sqrt(gx * gx + gy * gy); 40 | if (max < tmap[j * w + i]) { 41 | max = tmap[j * w + i]; 42 | } 43 | } 44 | } 45 | 46 | double top = max * 0.06; 47 | for (int i = 0; i < w; i++) { 48 | for (int j = 0; j < h; j++) { 49 | if (tmap[j * w + i] > top) { 50 | cmap[j * w + i] = mmap[j * w + i]; 51 | } else { 52 | cmap[j * w + i] = Color.WHITE; 53 | } 54 | } 55 | } 56 | return Bitmap.createBitmap(cmap, temp.getWidth(), temp.getHeight(), 57 | Bitmap.Config.ARGB_8888); 58 | } 59 | 60 | /** 61 | * 获取横向的 62 | * 63 | * @param x 第x行 64 | * @param y 第y列 65 | */ 66 | public static double GX(int x, int y, Bitmap bitmap) { 67 | double res = (-1) * getPixel(x - 1, y - 1, bitmap) + 1 68 | * getPixel(x + 1, y - 1, bitmap) + (-Math.sqrt(2)) 69 | * getPixel(x - 1, y, bitmap) + Math.sqrt(2) 70 | * getPixel(x + 1, y, bitmap) + (-1) 71 | * getPixel(x - 1, y + 1, bitmap) + 1 72 | * getPixel(x + 1, y + 1, bitmap); 73 | return res; 74 | } 75 | 76 | /** 77 | * 获取纵向的 78 | * 79 | * @param x 第x行 80 | * @param y 第y列 81 | */ 82 | public static double GY(int x, int y, Bitmap bitmap) { 83 | double res = 1 * getPixel(x - 1, y - 1, bitmap) + Math.sqrt(2) 84 | * getPixel(x, y - 1, bitmap) + 1 85 | * getPixel(x + 1, y - 1, bitmap) + (-1) 86 | * getPixel(x - 1, y + 1, bitmap) + (-Math.sqrt(2)) 87 | * getPixel(x, y + 1, bitmap) + (-1) 88 | * getPixel(x + 1, y + 1, bitmap); 89 | return res; 90 | } 91 | 92 | /** 93 | * 获取第x行第y列的色度 94 | * 95 | * @param x 第x行 96 | * @param y 第y列 97 | */ 98 | public static double getPixel(int x, int y, Bitmap bitmap) { 99 | if (x < 0 || x >= bitmap.getWidth() || y < 0 || y >= bitmap.getHeight()) 100 | return 0; 101 | return bitmap.getPixel(x, y); 102 | } 103 | 104 | /** 105 | * 转化成灰度图 106 | */ 107 | public static Bitmap toGrayscale(Bitmap bmpOriginal) { 108 | 109 | int width, height; 110 | height = bmpOriginal.getHeight(); 111 | width = bmpOriginal.getWidth(); 112 | 113 | Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, 114 | Bitmap.Config.RGB_565); 115 | Canvas c = new Canvas(bmpGrayscale); 116 | Paint paint = new Paint(); 117 | ColorMatrix cm = new ColorMatrix(); 118 | cm.setSaturation(0); 119 | ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm); 120 | paint.setColorFilter(f); 121 | c.drawBitmap(bmpOriginal, 0, 0, paint); 122 | return bmpGrayscale; 123 | } 124 | 125 | /** 126 | * Bitmap压缩 127 | */ 128 | public static Bitmap compress(final Bitmap bm, int reqWidth, int reqHeight) { 129 | int width = bm.getWidth(); 130 | int height = bm.getHeight(); 131 | 132 | if (height > reqHeight || width > reqWidth) { 133 | float scaleWidth = (float) reqWidth / width; 134 | float scaleHeight = (float) reqHeight / height; 135 | float scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight; 136 | 137 | Matrix matrix = new Matrix(); 138 | matrix.postScale(scale, scale); 139 | Bitmap result = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), 140 | bm.getHeight(), matrix, true); 141 | bm.recycle(); 142 | return result; 143 | } 144 | return bm; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /app/src/main/java/com/xishuang/imageviewprocess/algorithm/SpecialColorMatrix.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess.algorithm; 2 | 3 | /** 4 | * Author:xishuang 5 | * Date:2018.04.05 6 | * Des:通过特定的过滤算法实现的ColorMatrix 7 | */ 8 | public class SpecialColorMatrix { 9 | 10 | /** 11 | * 默认效果,不会改变图片 12 | */ 13 | private static final float[] DEFAULT = new float[]{ 14 | 1, 0, 0, 0, 0, 15 | 0, 1, 0, 0, 0, 16 | 0, 0, 1, 0, 0, 17 | 0, 0, 0, 1, 0 18 | }; 19 | 20 | /** 21 | * 怀旧效果 22 | *

23 | * R = 0.393*R + 0.769*G + 0.189*B; 24 | * G = 0.349*R + 0.686*G + 0.168*B; 25 | * B = 0.272*R + 0.534*G + 0.131*B; 26 | * A = A; 27 | *

28 | */ 29 | private static final float[] HUAIJIU = new float[]{ 30 | 0.393f, 0.769f, 0.189f, 0, 0, 31 | 0.349f, 0.686f, 0.168f, 0, 0, 32 | 0.272f, 0.534f, 0.131f, 0, 0, 33 | 0, 0, 0, 1, 0 34 | }; 35 | 36 | /** 37 | * 底片反转效果 38 | *

39 | * R = 255 - 1*R; 40 | * G = 255 - 1*G; 41 | * B = 255 - 1*B; 42 | * A = A; 43 | *

44 | */ 45 | private static final float[] DIPIAN = new float[]{ 46 | -1, 0, 0, 0, 255, 47 | 0, -1, 0, 0, 255, 48 | 0, 0, -1, 0, 255, 49 | 0, 0, 0, 1, 0 50 | }; 51 | 52 | /** 53 | * 灰度效果 54 | *

55 | * R = 0.33*R + 0.59*G + 0.11*B; 56 | * G = 0.33*R + 0.59*G + 0.11*B; 57 | * B = 0.33*R + 0.59*G + 0.11*B; 58 | * A = A; 59 | *

60 | */ 61 | private static final float[] GRAY = new float[]{ 62 | 0.33f, 0.59f, 0.11f, 0, 0, 63 | 0.33f, 0.59f, 0.11f, 0, 0, 64 | 0.33f, 0.59f, 0.11f, 0, 0, 65 | 0, 0, 0, 1, 0, 66 | }; 67 | 68 | /** 69 | * 高亮,提高色彩饱和度 70 | *

71 | * R = 1.438*R - 0.122*G - 0.016*B - 7.65; 72 | * G = -0.062*R + 1.378*G - 0.016*B + 12.75; 73 | * B = -0.062*R - 0.122*G + 1.483*B - 5.1; 74 | * A = A; 75 | *

76 | */ 77 | private static final float[] BRIGHT = new float[]{ 78 | 1.438f, -0.122f, -0.016f, 0, -7.65f, 79 | -0.062f, 1.378f, -0.016f, 0, 12.75f, 80 | -0.062f, -0.122f, 1.483f, 0, -5.1f, 81 | 0, 0, 0, 1, 0, 82 | }; 83 | 84 | public static float[] getDefault() { 85 | return DEFAULT.clone(); 86 | } 87 | 88 | public static float[] getHuaiJiu() { 89 | return HUAIJIU.clone(); 90 | } 91 | 92 | public static float[] getDiPian() { 93 | return DIPIAN.clone(); 94 | } 95 | 96 | public static float[] getGray() { 97 | return GRAY.clone(); 98 | } 99 | 100 | public static float[] getBright() { 101 | return BRIGHT.clone(); 102 | } 103 | 104 | /** 105 | * 特殊效果的模式 106 | */ 107 | public static class MODE { 108 | public static final int DEFAULT = 0; 109 | public static final int HUAIJIU = 1; 110 | public static final int DIPIAN = 2; 111 | public static final int GRAY = 3; 112 | public static final int BRIGHT = 4; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /app/src/main/java/com/xishuang/imageviewprocess/security/DecryptUtil.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess.security; 2 | 3 | import android.content.Context; 4 | import android.content.res.AssetManager; 5 | 6 | import java.io.ByteArrayOutputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.security.PublicKey; 10 | 11 | import javax.crypto.Cipher; 12 | import javax.crypto.CipherInputStream; 13 | import javax.crypto.spec.SecretKeySpec; 14 | 15 | public class DecryptUtil { 16 | private static final String SIMPLE_KEY_DATA = "testkey.dat"; 17 | 18 | /** 19 | * 获取解密之后的文件流 20 | */ 21 | public static InputStream onObtainInputStream(Context context) { 22 | try { 23 | AssetManager assetmanager = context.getAssets(); 24 | InputStream is = assetmanager.open("encrypt_测试.txt"); 25 | byte[] rawkey = getRawKey(context); 26 | 27 | //使用解密流,数据写出到基础OutputStream之前先对该会先对数据进行解密 28 | SecretKeySpec skeySpec = new SecretKeySpec(rawkey, "AES"); 29 | Cipher cipher = Cipher.getInstance("AES"); 30 | cipher.init(Cipher.DECRYPT_MODE, skeySpec); 31 | return new CipherInputStream(is, cipher); 32 | } catch (Exception e) { 33 | e.printStackTrace(); 34 | } 35 | return null; 36 | } 37 | 38 | /** 39 | * 获取解密之后的文件加密密钥 40 | */ 41 | private static byte[] getRawKey(Context context) throws Exception { 42 | //获取应用的签名密钥 43 | byte[] sign = SignKey.getSign(context); 44 | PublicKey pubKey = SignKey.getPublicKey(sign); 45 | //获取加密文件的密钥 46 | InputStream keyis = context.getAssets().open(SIMPLE_KEY_DATA); 47 | byte[] key = getData(keyis); 48 | //解密密钥 49 | return RSA.decrypt(key, pubKey); 50 | } 51 | 52 | 53 | private static byte[] getData(InputStream is) throws IOException { 54 | byte[] buffer = new byte[1024]; 55 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 56 | int offset; 57 | while ((offset = is.read(buffer)) != -1) { 58 | baos.write(buffer, 0, offset); 59 | } 60 | return baos.toByteArray(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/xishuang/imageviewprocess/security/RSA.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess.security; 2 | 3 | import java.security.PrivateKey; 4 | import java.security.PublicKey; 5 | import javax.crypto.Cipher; 6 | 7 | public class RSA { 8 | 9 | public static byte[] encrypt(byte []data, PrivateKey prikey) throws Exception { 10 | Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 11 | cipher.init(Cipher.ENCRYPT_MODE, prikey); 12 | return cipher.doFinal(data); 13 | } 14 | 15 | public static byte[] decrypt (byte []data, PublicKey pubkey) throws Exception { 16 | Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 17 | cipher.init(Cipher.DECRYPT_MODE, pubkey); 18 | return cipher.doFinal(data); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/xishuang/imageviewprocess/security/SignKey.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess.security; 2 | 3 | import android.content.Context; 4 | import android.content.pm.PackageInfo; 5 | import android.content.pm.PackageManager; 6 | import android.content.pm.PackageManager.NameNotFoundException; 7 | import android.content.pm.Signature; 8 | 9 | import java.io.ByteArrayInputStream; 10 | import java.security.PublicKey; 11 | import java.security.cert.CertificateException; 12 | import java.security.cert.CertificateFactory; 13 | import java.security.cert.X509Certificate; 14 | 15 | 16 | /** 17 | * Author:xishuang 18 | * Date:2018.05.06 19 | * Des:应用签名读取工具类 20 | */ 21 | public class SignKey { 22 | 23 | /** 24 | * 获取当前应用的签名 25 | * 26 | * @param context 上下文 27 | */ 28 | public static byte[] getSign(Context context) { 29 | PackageManager pm = context.getPackageManager(); 30 | try { 31 | PackageInfo info = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES); 32 | Signature[] signatures = info.signatures; 33 | if (signatures != null) { 34 | return signatures[0].toByteArray(); 35 | } 36 | } catch (NameNotFoundException e) { 37 | e.printStackTrace(); 38 | } 39 | return null; 40 | } 41 | 42 | /** 43 | * 根据签名去获取公钥 44 | */ 45 | public static PublicKey getPublicKey(byte[] signature) { 46 | try { 47 | CertificateFactory certFactory = CertificateFactory 48 | .getInstance("X.509"); 49 | X509Certificate cert = (X509Certificate) certFactory 50 | .generateCertificate(new ByteArrayInputStream(signature)); 51 | return cert.getPublicKey(); 52 | } catch (CertificateException e) { 53 | e.printStackTrace(); 54 | } 55 | return null; 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /app/src/main/java/com/xishuang/imageviewprocess/ui/ColorMatrixActivity.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess.ui; 2 | 3 | import android.graphics.ColorMatrix; 4 | import android.graphics.ColorMatrixColorFilter; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.RecyclerView; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.ImageView; 13 | import android.widget.SeekBar; 14 | import android.widget.TextView; 15 | import android.widget.Toast; 16 | 17 | import com.xishuang.imageviewprocess.util.ImageUtil; 18 | import com.xishuang.imageviewprocess.R; 19 | import com.xishuang.imageviewprocess.algorithm.SpecialColorMatrix; 20 | 21 | import java.text.DecimalFormat; 22 | import java.util.ArrayList; 23 | import java.util.HashMap; 24 | import java.util.List; 25 | import java.util.Map; 26 | 27 | /** 28 | * Author:xishuang 29 | * Date:2018.04.03 30 | * Des: ColorMatrixColorFilter的效果调试界面 31 | */ 32 | public class ColorMatrixActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener { 33 | 34 | private ImageView imageView; 35 | private TextView tvModeText; 36 | private TextView tvHueText; 37 | private TextView tvSaturationText; 38 | private TextView tvBrightnessText; 39 | private SeekBar sBHue; 40 | private SeekBar sBSaturation; 41 | private SeekBar sBBrightness; 42 | 43 | private List> mDataList; 44 | 45 | @Override 46 | protected void onCreate(Bundle savedInstanceState) { 47 | super.onCreate(savedInstanceState); 48 | setContentView(R.layout.activity_color_matrix); 49 | 50 | imageView = (ImageView) findViewById(R.id.color_matrix_img); 51 | tvModeText = (TextView) findViewById(R.id.color_matrix_mode); 52 | tvHueText = (TextView) findViewById(R.id.color_matrix_hue_text); 53 | tvSaturationText = (TextView) findViewById(R.id.color_matrix_saturation_text); 54 | tvBrightnessText = (TextView) findViewById(R.id.color_matrix_brightness_text); 55 | //SeekBar 56 | sBHue = (SeekBar) findViewById(R.id.color_matrix_hue); 57 | sBSaturation = (SeekBar) findViewById(R.id.color_matrix_saturation); 58 | sBBrightness = (SeekBar) findViewById(R.id.color_matrix_brightness); 59 | //RecyclerView 60 | RecyclerView recyclerView = (RecyclerView) findViewById(R.id.color_matrix_recycler_view); 61 | recyclerView.setLayoutManager(new LinearLayoutManager(this)); 62 | recyclerView.setAdapter(new ColorMatrixAdapter()); 63 | 64 | sBHue.setOnSeekBarChangeListener(this); 65 | sBSaturation.setOnSeekBarChangeListener(this); 66 | sBBrightness.setOnSeekBarChangeListener(this); 67 | 68 | mDataList = getData(); 69 | } 70 | 71 | @Override 72 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 73 | float hueValue = sBHue.getProgress() * 1.0f; 74 | float saturationValue = sBSaturation.getProgress() / 128f; 75 | float brightnessValue = sBBrightness.getProgress() / 128f; 76 | 77 | //展示出这三个值大小 78 | DecimalFormat format = new DecimalFormat(".0"); 79 | String value = format.format(saturationValue); 80 | tvHueText.setText("色调值:" + hueValue + "°"); 81 | tvSaturationText.setText("饱和度值:" + value); 82 | value = format.format(brightnessValue); 83 | tvBrightnessText.setText("亮度值:" + value); 84 | 85 | //图像处理 86 | ImageUtil.displayImageColorMatrixHSB(imageView, hueValue, saturationValue, brightnessValue); 87 | } 88 | 89 | @Override 90 | public void onStartTrackingTouch(SeekBar seekBar) { 91 | 92 | } 93 | 94 | @Override 95 | public void onStopTrackingTouch(SeekBar seekBar) { 96 | 97 | } 98 | 99 | /** 100 | * 数据初始化 101 | */ 102 | private List> getData() { 103 | List> data = new ArrayList<>(); 104 | addItem(data, "效果清空", SpecialColorMatrix.MODE.DEFAULT); 105 | addItem(data, "怀旧效果", SpecialColorMatrix.MODE.HUAIJIU); 106 | addItem(data, "底片反转", SpecialColorMatrix.MODE.DIPIAN); 107 | addItem(data, "灰度效果", SpecialColorMatrix.MODE.GRAY); 108 | addItem(data, "高亮效果", SpecialColorMatrix.MODE.BRIGHT); 109 | 110 | return data; 111 | } 112 | 113 | private void addItem(List> data, String title, int value) { 114 | Map map = new HashMap<>(); 115 | map.put("title", title); 116 | map.put("value", value); 117 | data.add(map); 118 | } 119 | 120 | class ColorMatrixAdapter extends RecyclerView.Adapter { 121 | 122 | @Override 123 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 124 | View view = LayoutInflater.from(ColorMatrixActivity.this).inflate(R.layout.activity_porter_duff_item, parent, false); 125 | return new ColorMatrixViewHolder(view); 126 | } 127 | 128 | @Override 129 | public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { 130 | if (holder instanceof ColorMatrixViewHolder) { 131 | ColorMatrixViewHolder colorMatrixViewHolder = (ColorMatrixViewHolder) holder; 132 | colorMatrixViewHolder.itemTextView.setText((position + 1) + "、" + mDataList.get(position).get("title")); 133 | colorMatrixViewHolder.itemTextView.setOnClickListener(new View.OnClickListener() { 134 | @Override 135 | public void onClick(View v) { 136 | int position = holder.getLayoutPosition(); 137 | ImageUtil.displayImageColorMatrix(imageView, (Integer) mDataList.get(position).get("value")); 138 | tvModeText.setText("模式:" + mDataList.get(position).get("title")); 139 | } 140 | }); 141 | } 142 | } 143 | 144 | @Override 145 | public int getItemCount() { 146 | return mDataList.size(); 147 | } 148 | } 149 | 150 | class ColorMatrixViewHolder extends RecyclerView.ViewHolder { 151 | 152 | TextView itemTextView; 153 | 154 | ColorMatrixViewHolder(View itemView) { 155 | super(itemView); 156 | itemTextView = (TextView) itemView.findViewById(R.id.porter_duff_item_text); 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /app/src/main/java/com/xishuang/imageviewprocess/ui/LightingActivity.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess.ui; 2 | 3 | import android.graphics.Color; 4 | import android.graphics.LightingColorFilter; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.widget.ImageView; 8 | import android.widget.SeekBar; 9 | import android.widget.TextView; 10 | 11 | import com.xishuang.imageviewprocess.R; 12 | import com.xishuang.imageviewprocess.util.ImageUtil; 13 | 14 | /** 15 | * Author:xishuang 16 | * Date:2018.04.03 17 | * Des: LightingColorFilter的效果调试界面 18 | */ 19 | public class LightingActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener { 20 | 21 | private ImageView imageView; 22 | private SeekBar sBPlusA; 23 | private SeekBar sBPlusR; 24 | private SeekBar sBPlusG; 25 | private SeekBar sBPlusB; 26 | private SeekBar sBAddA; 27 | private SeekBar sBAddR; 28 | private SeekBar sBAddG; 29 | private SeekBar sBAddB; 30 | private TextView tvPlusColorText; 31 | private TextView tvPlusColor; 32 | private TextView tvAddColorText; 33 | private TextView tvAddColor; 34 | 35 | 36 | @Override 37 | protected void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_lighting); 40 | 41 | imageView = (ImageView) findViewById(R.id.lighting_img); 42 | 43 | sBPlusA = (SeekBar) findViewById(R.id.lighting_plus_bar_A); 44 | sBPlusR = (SeekBar) findViewById(R.id.lighting_plus_bar_R); 45 | sBPlusG = (SeekBar) findViewById(R.id.lighting_plus_bar_G); 46 | sBPlusB = (SeekBar) findViewById(R.id.lighting_plus_bar_B); 47 | 48 | sBAddA = (SeekBar) findViewById(R.id.lighting_add_bar_A); 49 | sBAddR = (SeekBar) findViewById(R.id.lighting_add_bar_R); 50 | sBAddG = (SeekBar) findViewById(R.id.lighting_add_bar_G); 51 | sBAddB = (SeekBar) findViewById(R.id.lighting_add_bar_B); 52 | 53 | tvPlusColorText = (TextView) findViewById(R.id.lighting_plus_color_text); 54 | tvPlusColor = (TextView) findViewById(R.id.lighting_plus_color); 55 | tvAddColorText = (TextView) findViewById(R.id.lighting_add_color_text); 56 | tvAddColor = (TextView) findViewById(R.id.lighting_add_color); 57 | 58 | sBPlusA.setOnSeekBarChangeListener(this); 59 | sBPlusR.setOnSeekBarChangeListener(this); 60 | sBPlusG.setOnSeekBarChangeListener(this); 61 | sBPlusB.setOnSeekBarChangeListener(this); 62 | sBAddA.setOnSeekBarChangeListener(this); 63 | sBAddR.setOnSeekBarChangeListener(this); 64 | sBAddG.setOnSeekBarChangeListener(this); 65 | sBAddB.setOnSeekBarChangeListener(this); 66 | } 67 | 68 | @Override 69 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 70 | 71 | //透明度也加上,透明度不参与计算,所以设置了也是默认无效的 72 | String plusText = "Plus颜色值(ARGB):#" + Integer.toHexString(sBPlusA.getProgress()) + "-" 73 | + Integer.toHexString(sBPlusR.getProgress()) + "-" 74 | + Integer.toHexString(sBPlusG.getProgress()) + "-" 75 | + Integer.toHexString(sBPlusB.getProgress()); 76 | int plusColor = Color.argb(sBPlusA.getProgress(), sBPlusR.getProgress(), sBPlusG.getProgress(), sBPlusB.getProgress()); 77 | tvPlusColorText.setText(plusText); 78 | tvPlusColor.setBackgroundColor(plusColor); 79 | 80 | String addText = "Add颜色值(ARGB):#" + Integer.toHexString(sBAddA.getProgress()) + "-" 81 | + Integer.toHexString(sBAddR.getProgress()) + "-" 82 | + Integer.toHexString(sBAddG.getProgress()) + "-" 83 | + Integer.toHexString(sBAddB.getProgress()); 84 | int addColor = Color.argb(sBAddA.getProgress(), sBAddR.getProgress(), sBAddG.getProgress(), sBAddB.getProgress()); 85 | tvAddColorText.setText(addText); 86 | tvAddColor.setBackgroundColor(addColor); 87 | 88 | ImageUtil.displayImageLighting(imageView, plusColor, addColor); 89 | } 90 | 91 | @Override 92 | public void onStartTrackingTouch(SeekBar seekBar) { 93 | 94 | } 95 | 96 | @Override 97 | public void onStopTrackingTouch(SeekBar seekBar) { 98 | 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /app/src/main/java/com/xishuang/imageviewprocess/ui/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess.ui; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | import android.widget.TextView; 8 | 9 | import com.xishuang.imageviewprocess.R; 10 | import com.xishuang.imageviewprocess.security.DecryptUtil; 11 | 12 | import java.io.BufferedReader; 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.io.InputStreamReader; 16 | 17 | public class MainActivity extends AppCompatActivity implements View.OnClickListener { 18 | 19 | private TextView contentTv; 20 | 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_main_colorfilter); 25 | 26 | findViewById(R.id.bt_lighting).setOnClickListener(this); 27 | findViewById(R.id.bt_porterduff).setOnClickListener(this); 28 | findViewById(R.id.bt_colormatrix).setOnClickListener(this); 29 | 30 | contentTv = (TextView) findViewById(R.id.bt_text); 31 | 32 | inputData(); 33 | } 34 | 35 | private void inputData() { 36 | InputStream in = DecryptUtil.onObtainInputStream(this); 37 | 38 | try { 39 | BufferedReader reader = new BufferedReader(new InputStreamReader(in, "GBK")); 40 | StringBuilder sb = new StringBuilder(); 41 | String line; 42 | while ((line = reader.readLine()) != null) { 43 | sb.append(line + "\n"); 44 | } 45 | contentTv.setText(sb.toString()); 46 | } catch (IOException e) { 47 | e.printStackTrace(); 48 | } finally { 49 | try { 50 | in.close(); 51 | } catch (IOException e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | } 56 | 57 | @Override 58 | public void onClick(View v) { 59 | if (v.getId() == R.id.bt_lighting) { 60 | Intent intent = new Intent(this, LightingActivity.class); 61 | startActivity(intent); 62 | } else if (v.getId() == R.id.bt_porterduff) { 63 | Intent intent = new Intent(this, PorterDuffActivity.class); 64 | startActivity(intent); 65 | } else if (v.getId() == R.id.bt_colormatrix) { 66 | Intent intent = new Intent(this, ColorMatrixActivity.class); 67 | startActivity(intent); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/xishuang/imageviewprocess/ui/PorterDuffActivity.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess.ui; 2 | 3 | import android.graphics.Color; 4 | import android.graphics.PorterDuff; 5 | import android.graphics.PorterDuffColorFilter; 6 | import android.os.Bundle; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.support.v7.widget.LinearLayoutManager; 9 | import android.support.v7.widget.RecyclerView; 10 | import android.view.LayoutInflater; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.ImageView; 14 | import android.widget.SeekBar; 15 | import android.widget.TextView; 16 | import android.widget.Toast; 17 | 18 | import com.xishuang.imageviewprocess.R; 19 | import com.xishuang.imageviewprocess.util.ImageUtil; 20 | 21 | import java.util.ArrayList; 22 | import java.util.HashMap; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | /** 27 | * Author:xishuang 28 | * Date:2018.04.03 29 | * Des: PorterDuffColorFilter的效果调试界面 30 | */ 31 | public class PorterDuffActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener { 32 | 33 | private SeekBar sBR; 34 | private SeekBar sBG; 35 | private SeekBar sBB; 36 | private SeekBar sBA; 37 | private ImageView imageView; 38 | private TextView tvColorText; 39 | private TextView tvColor; 40 | 41 | private PorterDuff.Mode mode = PorterDuff.Mode.DST; 42 | private int mColor; 43 | 44 | private List> mDataList; 45 | private TextView tvModeText; 46 | 47 | @Override 48 | protected void onCreate(Bundle savedInstanceState) { 49 | super.onCreate(savedInstanceState); 50 | setContentView(R.layout.activity_porter_duff); 51 | 52 | imageView = (ImageView) findViewById(R.id.porter_duff_img); 53 | //SeekBar 54 | sBA = (SeekBar) findViewById(R.id.porter_duff_bar_A); 55 | sBR = (SeekBar) findViewById(R.id.porter_duff_bar_R); 56 | sBG = (SeekBar) findViewById(R.id.porter_duff_bar_G); 57 | sBB = (SeekBar) findViewById(R.id.porter_duff_bar_B); 58 | 59 | //选中的颜色值 60 | tvColorText = (TextView) findViewById(R.id.porter_duff_color_text); 61 | tvModeText = (TextView) findViewById(R.id.porter_duff_mode); 62 | tvColor = (TextView) findViewById(R.id.porter_duff_color); 63 | //RecyclerView 64 | RecyclerView recyclerView = (RecyclerView) findViewById(R.id.porter_duff_recycler_view); 65 | recyclerView.setLayoutManager(new LinearLayoutManager(this)); 66 | recyclerView.setAdapter(new PorterDuffAdapter()); 67 | 68 | sBA.setOnSeekBarChangeListener(this); 69 | sBR.setOnSeekBarChangeListener(this); 70 | sBG.setOnSeekBarChangeListener(this); 71 | sBB.setOnSeekBarChangeListener(this); 72 | 73 | mDataList = getData(); 74 | } 75 | 76 | @Override 77 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 78 | String addText = "源颜色值(ARGB):#" + Integer.toHexString(sBA.getProgress()) + "-" 79 | + Integer.toHexString(sBR.getProgress()) + "-" 80 | + Integer.toHexString(sBG.getProgress()) + "-" 81 | + Integer.toHexString(sBB.getProgress()); 82 | mColor = Color.argb(sBA.getProgress(), sBR.getProgress(), sBG.getProgress(), sBB.getProgress()); 83 | tvColorText.setText(addText); 84 | tvColor.setBackgroundColor(mColor); 85 | 86 | ImageUtil.displayImagePorterDuff(imageView, mColor, mode); 87 | } 88 | 89 | @Override 90 | public void onStartTrackingTouch(SeekBar seekBar) { 91 | 92 | } 93 | 94 | @Override 95 | public void onStopTrackingTouch(SeekBar seekBar) { 96 | 97 | } 98 | 99 | /** 100 | * 数据初始化 101 | */ 102 | private List> getData() { 103 | List> data = new ArrayList<>(); 104 | addItem(data, "CLEAR(Alpha合成)", PorterDuff.Mode.CLEAR); 105 | addItem(data, "SRC(Alpha合成)", PorterDuff.Mode.SRC); 106 | addItem(data, "DST(Alpha合成)", PorterDuff.Mode.DST); 107 | addItem(data, "SRC_OVER(Alpha合成)", PorterDuff.Mode.SRC_OVER); 108 | addItem(data, "DST_OVER(Alpha合成)", PorterDuff.Mode.DST_OVER); 109 | addItem(data, "SRC_IN(Alpha合成)", PorterDuff.Mode.SRC_IN); 110 | addItem(data, "DST_IN(Alpha合成)", PorterDuff.Mode.DST_IN); 111 | addItem(data, "SRC_OUT(Alpha合成)", PorterDuff.Mode.SRC_OUT); 112 | addItem(data, "DST_OUT(Alpha合成)", PorterDuff.Mode.DST_OUT); 113 | addItem(data, "SRC_ATOP(Alpha合成)", PorterDuff.Mode.SRC_ATOP); 114 | addItem(data, "DST_ATOP(Alpha合成)", PorterDuff.Mode.DST_ATOP); 115 | addItem(data, "DARKEN(混合)", PorterDuff.Mode.DARKEN); 116 | addItem(data, "LIGHTEN(混合)", PorterDuff.Mode.LIGHTEN); 117 | addItem(data, "MULTIPLY(混合)", PorterDuff.Mode.MULTIPLY); 118 | addItem(data, "SCREEN(混合)", PorterDuff.Mode.SCREEN); 119 | addItem(data, "ADD(混合)", PorterDuff.Mode.ADD); 120 | addItem(data, "OVERLAY(混合)", PorterDuff.Mode.OVERLAY); 121 | 122 | return data; 123 | } 124 | 125 | private void addItem(List> data, String title, PorterDuff.Mode value) { 126 | Map map = new HashMap<>(); 127 | map.put("title", title); 128 | map.put("value", value); 129 | data.add(map); 130 | } 131 | 132 | class PorterDuffAdapter extends RecyclerView.Adapter { 133 | 134 | @Override 135 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 136 | View view = LayoutInflater.from(PorterDuffActivity.this).inflate(R.layout.activity_porter_duff_item, parent, false); 137 | return new PorterDuffViewHolder(view); 138 | } 139 | 140 | @Override 141 | public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { 142 | if (holder instanceof PorterDuffViewHolder) { 143 | PorterDuffViewHolder porterDuffViewHolder = (PorterDuffViewHolder) holder; 144 | porterDuffViewHolder.itemTextView.setText((position + 1) + "、" + mDataList.get(position).get("title")); 145 | porterDuffViewHolder.itemTextView.setOnClickListener(new View.OnClickListener() { 146 | @Override 147 | public void onClick(View v) { 148 | int position = holder.getLayoutPosition(); 149 | mode = (PorterDuff.Mode) mDataList.get(position).get("value"); 150 | imageView.setColorFilter(new PorterDuffColorFilter(mColor, mode)); 151 | tvModeText.setText("模式:" + mDataList.get(position).get("title")); 152 | } 153 | }); 154 | } 155 | } 156 | 157 | @Override 158 | public int getItemCount() { 159 | return mDataList.size(); 160 | } 161 | } 162 | 163 | class PorterDuffViewHolder extends RecyclerView.ViewHolder { 164 | 165 | TextView itemTextView; 166 | 167 | PorterDuffViewHolder(View itemView) { 168 | super(itemView); 169 | itemTextView = (TextView) itemView.findViewById(R.id.porter_duff_item_text); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /app/src/main/java/com/xishuang/imageviewprocess/util/ImageUtil.java: -------------------------------------------------------------------------------- 1 | package com.xishuang.imageviewprocess.util; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.graphics.ColorFilter; 7 | import android.graphics.ColorMatrix; 8 | import android.graphics.ColorMatrixColorFilter; 9 | import android.graphics.LightingColorFilter; 10 | import android.graphics.PorterDuff; 11 | import android.graphics.PorterDuffColorFilter; 12 | import android.graphics.drawable.Drawable; 13 | import android.support.annotation.ColorInt; 14 | import android.support.annotation.NonNull; 15 | import android.widget.ImageView; 16 | 17 | import com.xishuang.imageviewprocess.algorithm.SobelAlgorithm; 18 | import com.xishuang.imageviewprocess.algorithm.SpecialColorMatrix; 19 | 20 | /** 21 | * Author : xishuang 22 | * Date : 2018.04.02 23 | * Desc : 图片处理中心 24 | */ 25 | public class ImageUtil { 26 | private static ColorMatrix colorMatrix = new ColorMatrix(); 27 | /** 28 | * 色调,改变颜色 29 | */ 30 | private static ColorMatrix hueMatrix = new ColorMatrix(); 31 | /** 32 | * 饱和度,改变颜色的纯度 33 | */ 34 | private static ColorMatrix saturationMatrix = new ColorMatrix(); 35 | /** 36 | * 亮度,控制明暗 37 | */ 38 | private static ColorMatrix brightnessMatrix = new ColorMatrix(); 39 | 40 | /** 41 | * 使用Sobel算法边缘检测 42 | */ 43 | public static void displayImageSobel(Context context, ImageView imageView, int res_id) { 44 | Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), res_id); 45 | bitmap = SobelAlgorithm.Sobel(bitmap); 46 | imageView.setImageBitmap(bitmap); 47 | } 48 | 49 | /** 50 | * 通过乘积和加来操作的LightingColorFilter 51 | * 52 | * @param mul 乘积分量 53 | * @param add 加法分量 54 | */ 55 | public static void displayImageLighting(ImageView imageView, int mul, int add) { 56 | imageView.setColorFilter(new LightingColorFilter(mul, add)); 57 | } 58 | 59 | /** 60 | * 通过源颜色值和PorterDuff模式来操作的PorterDuffColorFilter 61 | * 62 | * @param color 源颜色值 63 | * @param mode PorterDuff模式 64 | */ 65 | public static void displayImagePorterDuff(ImageView imageView, @ColorInt int color, @NonNull PorterDuff.Mode mode) { 66 | imageView.setColorFilter(new PorterDuffColorFilter(color, mode)); 67 | } 68 | 69 | /** 70 | * 通过色调来操作ImageView的ColorMatrixColorFilter 71 | * 72 | * @param hueValue 色调值 73 | */ 74 | public static void displayImageColorMatrixH(ImageView imageView, float hueValue) { 75 | displayImageColorMatrixHSB(imageView, hueValue, 1, 1); 76 | } 77 | 78 | /** 79 | * 通过饱和度来操作ImageView的ColorMatrixColorFilter 80 | * 81 | * @param saturationValue 饱和度值 82 | */ 83 | public static void displayImageColorMatrixS(ImageView imageView, float saturationValue) { 84 | displayImageColorMatrixHSB(imageView, 0, saturationValue, 1); 85 | } 86 | 87 | /** 88 | * 通过亮度来操作ImageView的ColorMatrixColorFilter 89 | * 90 | * @param brightnessValue 亮度值 91 | */ 92 | public static void displayImageColorMatrixB(ImageView imageView, float brightnessValue) { 93 | displayImageColorMatrixHSB(imageView, 0, 1, brightnessValue); 94 | } 95 | 96 | /** 97 | * 通过色调、饱和度、亮度来操作ImageView的ColorMatrixColorFilter 98 | * 99 | * @param hueValue 色调值 100 | * @param saturationValue 饱和度值 101 | * @param brightnessValue 亮度值 102 | */ 103 | public static void displayImageColorMatrixHSB(ImageView imageView, float hueValue, float saturationValue, float brightnessValue) { 104 | //设置色相,为0°和360的时候相当于原图 105 | hueMatrix.reset(); 106 | hueMatrix.setRotate(0, hueValue); 107 | hueMatrix.setRotate(1, hueValue); 108 | hueMatrix.setRotate(2, hueValue); 109 | 110 | //设置饱和度,为1的时候相当于原图 111 | saturationMatrix.reset(); 112 | saturationMatrix.setSaturation(saturationValue); 113 | 114 | //亮度,为1的时候相当于原图 115 | brightnessMatrix.reset(); 116 | brightnessMatrix.setScale(brightnessValue, brightnessValue, brightnessValue, 1); 117 | 118 | //将上面三种效果和选中的模式混合在一起 119 | colorMatrix.reset(); 120 | colorMatrix.postConcat(hueMatrix); 121 | colorMatrix.postConcat(saturationMatrix); 122 | colorMatrix.postConcat(brightnessMatrix); 123 | 124 | imageView.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); 125 | } 126 | 127 | /** 128 | * 针对特定ColorMatrixColorFilter实现特殊效果 129 | */ 130 | public static void displayImageColorMatrix(ImageView imageView, int mode) { 131 | float[] matrix = SpecialColorMatrix.getDefault(); 132 | switch (mode) { 133 | case SpecialColorMatrix.MODE.DEFAULT: 134 | matrix = SpecialColorMatrix.getDefault(); 135 | break; 136 | case SpecialColorMatrix.MODE.HUAIJIU: 137 | matrix = SpecialColorMatrix.getHuaiJiu(); 138 | break; 139 | case SpecialColorMatrix.MODE.DIPIAN: 140 | matrix = SpecialColorMatrix.getDiPian(); 141 | break; 142 | case SpecialColorMatrix.MODE.GRAY: 143 | matrix = SpecialColorMatrix.getGray(); 144 | break; 145 | case SpecialColorMatrix.MODE.BRIGHT: 146 | matrix = SpecialColorMatrix.getBright(); 147 | break; 148 | default: 149 | } 150 | imageView.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(matrix))); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/bg5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rchaocai/ImageViewProcess/7c564965a468cd23bce146f995772836f1addba8/app/src/main/res/drawable-xhdpi/bg5.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_color_matrix.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 19 | 20 | 27 | 28 | 29 | 35 | 36 | 42 | 43 | 49 | 50 | 56 | 57 | 58 | 64 | 65 | 70 | 71 | 78 | 79 | 86 | 87 | 88 | 93 | 94 | 101 | 102 | 109 | 110 | 111 | 116 | 117 | 124 | 125 | 132 | 133 | 134 | 135 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_lighting.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 19 | 20 | 27 | 28 | 29 | 34 | 35 | 41 | 42 | 49 | 50 | 51 | 56 | 57 | 63 | 64 | 71 | 72 | 73 | 78 | 79 | 85 | 86 | 93 | 94 | 95 | 100 | 101 | 107 | 108 | 115 | 116 | 117 | 118 | 123 | 124 | 130 | 131 | 138 | 139 | 140 | 146 | 147 | 153 | 154 | 161 | 162 | 163 | 168 | 169 | 175 | 176 | 184 | 185 | 186 | 191 | 192 | 199 | 200 | 207 | 208 | 209 | 214 | 215 | 221 | 222 | 229 | 230 | 231 | 232 | 237 | 238 | 244 | 245 | 252 | 253 | 254 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main_colorfilter.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 |