├── .gitignore
├── .idea
├── .name
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── example
│ │ └── jimageeditdemo
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── apk
│ │ └── app-debug.apk
│ ├── java
│ │ └── com
│ │ │ ├── example
│ │ │ └── jimageeditdemo
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── api
│ │ │ │ ├── BitmapFilter.java
│ │ │ │ ├── BlockFilter.java
│ │ │ │ ├── CartonFilter.java
│ │ │ │ ├── EclosionFilter.java
│ │ │ │ ├── GrayFilter.java
│ │ │ │ ├── HahaFilter.java
│ │ │ │ ├── IceFilter.java
│ │ │ │ ├── InvertFilter.java
│ │ │ │ ├── LightFilter.java
│ │ │ │ ├── LomoFilter.java
│ │ │ │ ├── MoltenFilter.java
│ │ │ │ ├── OilFilter.java
│ │ │ │ ├── OldFilter.java
│ │ │ │ ├── ReliefFilter.java
│ │ │ │ └── SoftnessFilter.java
│ │ │ └── pmmq
│ │ │ └── pmmqproject
│ │ │ ├── config
│ │ │ └── Constant.java
│ │ │ ├── ui
│ │ │ ├── picture
│ │ │ │ ├── CropActivity.java
│ │ │ │ ├── CropImageView.java
│ │ │ │ ├── HighlightView.java
│ │ │ │ ├── ImageViewTouchBase.java
│ │ │ │ ├── MonitoredActivity.java
│ │ │ │ ├── RotateBitmap.java
│ │ │ │ ├── TakePicActivity.java
│ │ │ │ ├── TouchImageView.java
│ │ │ │ ├── WaterMarkActivity.java
│ │ │ │ └── WaterMarkActivity_ImageFilter.java
│ │ │ └── tag
│ │ │ │ ├── AddTagActivity.java
│ │ │ │ ├── EmojiconTextView.java
│ │ │ │ ├── PreViewActivity.java
│ │ │ │ ├── ShowTagActivity.java
│ │ │ │ ├── TagInfo.java
│ │ │ │ ├── TagView.java
│ │ │ │ ├── TagViewLeft.java
│ │ │ │ └── TagViewRight.java
│ │ │ └── util
│ │ │ ├── BitmapLoader.java
│ │ │ ├── FileUtils.java
│ │ │ ├── Logger.java
│ │ │ └── NormalUtils.java
│ └── res
│ │ ├── anim
│ │ ├── black_anim.xml
│ │ └── white_anim.xml
│ │ ├── drawable-hdpi
│ │ ├── brand_tag_point_black_bg.png
│ │ ├── brand_tag_point_white_bg.png
│ │ ├── camera_crop_height.png
│ │ ├── camera_crop_width.png
│ │ ├── ic_launcher.png
│ │ ├── icon_place.png
│ │ ├── icon_tag_brand_active.png
│ │ ├── icon_tag_brand_normal.png
│ │ ├── icon_tag_geolocation_active.png
│ │ ├── icon_tag_geolocation_normal.png
│ │ ├── icon_tag_user_active.png
│ │ ├── icon_tag_user_normal.png
│ │ ├── indicator_autocrop.png
│ │ ├── tag_text_bg.9.png
│ │ ├── tag_text_bg_left.9.png
│ │ ├── tag_text_bg_right.9.png
│ │ ├── wm_1.png
│ │ ├── wm_2.png
│ │ ├── wm_3.png
│ │ ├── wm_4.png
│ │ ├── wm_5.png
│ │ └── wm_6.png
│ │ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ │ ├── drawable-xhdpi
│ │ ├── huishu.jpg
│ │ └── ic_launcher.png
│ │ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── layout
│ │ ├── activity_add_tag.xml
│ │ ├── activity_crop.xml
│ │ ├── activity_main.xml
│ │ ├── activity_pre_view.xml
│ │ ├── activity_show_tag.xml
│ │ ├── activity_take_pic.xml
│ │ ├── activity_water_mark.xml
│ │ ├── activity_water_mark_image_filter.xml
│ │ ├── fragment_main.xml
│ │ ├── tag_view_left.xml
│ │ └── tag_view_right.xml
│ │ ├── menu
│ │ └── main.xml
│ │ ├── values-v11
│ │ └── styles.xml
│ │ ├── values-v14
│ │ └── styles.xml
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── jimageeditdemo
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | BiaoQian
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
24 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
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 | Android API 19 Platform
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AndroidtagView
2 | Android 图片裁剪、添加水印、标签。仿nice添加标签
3 |
4 | #此贴在安卓bus上有引用,引用地址如下。
5 | http://www.apkbus.com/forum.php?mod=viewthread&tid=254407&extra=page%3D2%26filter%3Dsortid%26orderby%3Ddateline%26sortid%3D12
6 |
7 |
8 | #先看效果图
9 | ##1,拍照或者选择照片
10 | 
11 | ##2,对照片进行裁剪
12 | 
13 | ##3,添加贴图
14 | 
15 | ##4,动态添加多个标签
16 | 
17 |
18 | ##5,完成后可以保存图片
19 | 
20 |
21 | #这个项目可以直接导入到Android studio中,直接运行。大家可以自己研究下,直接使用到你自己的项目中。
22 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | applicationId "com.example.jimageeditdemo"
9 | minSdkVersion 14
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | testCompile 'junit:junit:4.12'
25 | compile 'com.android.support:appcompat-v7:23.0.1'
26 | }
27 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\qcl\as\android-sdk-windows/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/example/jimageeditdemo/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.example.jimageeditdemo;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
40 |
45 |
46 |
47 |
48 |
53 |
54 |
55 |
60 |
61 |
62 |
67 |
68 |
69 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/app/src/main/apk/app-debug.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/apk/app-debug.apk
--------------------------------------------------------------------------------
/app/src/main/java/com/example/jimageeditdemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.jimageeditdemo;
2 |
3 | import android.support.v7.app.ActionBarActivity;
4 | import android.support.v7.app.ActionBar;
5 | import android.support.v4.app.Fragment;
6 | import android.os.Bundle;
7 | import android.view.LayoutInflater;
8 | import android.view.Menu;
9 | import android.view.MenuItem;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.os.Build;
13 |
14 | public class MainActivity extends ActionBarActivity {
15 |
16 | @Override
17 | protected void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 | setContentView(R.layout.activity_main);
20 |
21 | if (savedInstanceState == null) {
22 | getSupportFragmentManager().beginTransaction()
23 | .add(R.id.container, new PlaceholderFragment())
24 | .commit();
25 | }
26 | }
27 |
28 |
29 | @Override
30 | public boolean onCreateOptionsMenu(Menu menu) {
31 |
32 | // Inflate the menu; this adds items to the action bar if it is present.
33 | getMenuInflater().inflate(R.menu.main, menu);
34 | return true;
35 | }
36 |
37 | @Override
38 | public boolean onOptionsItemSelected(MenuItem item) {
39 | // Handle action bar item clicks here. The action bar will
40 | // automatically handle clicks on the Home/Up button, so long
41 | // as you specify a parent activity in AndroidManifest.xml.
42 | int id = item.getItemId();
43 | if (id == R.id.action_settings) {
44 | return true;
45 | }
46 | return super.onOptionsItemSelected(item);
47 | }
48 |
49 | /**
50 | * A placeholder fragment containing a simple view.
51 | */
52 | public static class PlaceholderFragment extends Fragment {
53 |
54 | public PlaceholderFragment() {
55 | }
56 |
57 | @Override
58 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
59 | Bundle savedInstanceState) {
60 | View rootView = inflater.inflate(R.layout.fragment_main, container, false);
61 | return rootView;
62 | }
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/jimageeditdemo/api/BitmapFilter.java:
--------------------------------------------------------------------------------
1 | package com.example.jimageeditdemo.api;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | /**
6 | * 滤镜效果的类,定义了基本的渲染方法
7 | *
8 | */
9 | public class BitmapFilter {
10 | /**
11 | * 所有滤镜效果的id
12 | */
13 | public static final int GRAY_STYLE = 1; // 黑白效果
14 | public static final int BLOCK_STYLE = 2; // 版画
15 | public static final int OLD_STYLE = 3; // 怀旧效果
16 | public static final int ICE_STYLE = 4; //冰冻效果
17 | public static final int CARTON_STYLE = 5; //连环画效果
18 | public static final int MOLTEN_STYLE = 6; //铸融效果
19 | public static final int SOFTNESS_STYLE = 7; //柔化效果
20 | public static final int ECLOSION_STYLE = 8; //羽化效果
21 | public static final int RELIEF_STYLE = 9; // 浮雕效果
22 | public static final int OIL_STYLE = 10; // 油画效果
23 | public static final int INVERT_STYLE = 11; // 反色效果
24 | public static final int LIGHT_STYLE = 12; // 光照效果
25 | public static final int LOMO_STYLE = 13; //LOMO效果
26 | public static final int HAHA_STYLE = 14; //哈哈镜效果
27 |
28 | /**
29 | * 设置滤镜效果,
30 | * @param bitmap
31 | * @param
32 | */
33 | public static Bitmap changeStyle(Bitmap bitmap, int styleNo) {
34 | Bitmap newBitmap = null;
35 | switch(styleNo){
36 | case GRAY_STYLE:
37 | newBitmap = GrayFilter.changeToGray(bitmap);
38 | break;
39 | case BLOCK_STYLE:
40 | newBitmap = BlockFilter.changeToBlock(bitmap);
41 | break;
42 | case OLD_STYLE:
43 | newBitmap = OldFilter.changeToOld(bitmap);
44 | break;
45 | case ICE_STYLE:
46 | newBitmap = IceFilter.changeToIce(bitmap);
47 | break;
48 | case CARTON_STYLE:
49 | newBitmap = CartonFilter.changeToCarton(bitmap);
50 | break;
51 | case MOLTEN_STYLE:
52 | newBitmap = MoltenFilter.changeToMolten(bitmap);
53 | break;
54 | case SOFTNESS_STYLE:
55 | newBitmap = SoftnessFilter.changeToSoftness(bitmap);
56 | break;
57 | case ECLOSION_STYLE:
58 | newBitmap = EclosionFilter.changeToEclosion(bitmap);
59 | break;
60 | case RELIEF_STYLE:
61 | newBitmap = ReliefFilter.changeToRelief(bitmap);
62 | break;
63 | case OIL_STYLE:
64 | newBitmap = OilFilter.changeToOil(bitmap);
65 | break;
66 | case INVERT_STYLE:
67 | newBitmap = InvertFilter.chageToInvert(bitmap);
68 | break;
69 | case LIGHT_STYLE:
70 | newBitmap = LightFilter.changeToLight(bitmap);
71 | break;
72 | case LOMO_STYLE:
73 | newBitmap = LomoFilter.changeToLomo(bitmap);
74 | break;
75 | case HAHA_STYLE:
76 | newBitmap = HahaFilter.changeToHaha(bitmap);
77 | break;
78 | default:
79 | newBitmap = bitmap;
80 | break;
81 | }
82 |
83 | return newBitmap;
84 | }
85 | }
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/jimageeditdemo/api/BlockFilter.java:
--------------------------------------------------------------------------------
1 | package com.example.jimageeditdemo.api;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Color;
5 |
6 | public class BlockFilter {
7 | // 版画效果函数
8 | public static Bitmap changeToBlock(Bitmap bitmap) {
9 | int width = bitmap.getWidth();
10 | int height = bitmap.getHeight();
11 |
12 | int dst[] = new int[width * height];
13 | bitmap.getPixels(dst, 0, width, 0, 0, width, height);
14 |
15 | int iPixel = 0;
16 | int i, j, color, pos;
17 | for (j = 0; j < height; j++) {
18 | for (i = 0; i < width; i++) {
19 | pos = j * width + i;
20 | color = dst[pos];
21 | int avg = (Color.red(color) + Color.green(color) + Color.blue(color)) / 3;
22 | if (avg >= 100)
23 | iPixel = 255;
24 | else
25 | iPixel = 0;
26 |
27 | dst[pos] = Color.rgb(iPixel, iPixel, iPixel);
28 | }
29 | }
30 |
31 | Bitmap bmpReturn = Bitmap.createBitmap(width, height,
32 | Bitmap.Config.RGB_565);
33 | bmpReturn.setPixels(dst, 0, width, 0, 0, width, height);
34 | return bmpReturn;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/jimageeditdemo/api/CartonFilter.java:
--------------------------------------------------------------------------------
1 | package com.example.jimageeditdemo.api;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Color;
5 |
6 | public class CartonFilter {
7 | // 连环画效果
8 | public static Bitmap changeToCarton(Bitmap bitmap) {
9 | int width = bitmap.getWidth();
10 | int height = bitmap.getHeight();
11 | int dst[] = new int[width * height];
12 | bitmap.getPixels(dst, 0, width, 0, 0, width, height);
13 |
14 | int R, G, B, pixel;
15 | int pos, pixColor;
16 | for (int y = 0; y < height; y++) {
17 | for (int x = 0; x < width; x++) {
18 | pos = y * width + x;
19 | pixColor = dst[pos];
20 | R = Color.red(pixColor); // (color >> 16) & 0xFF
21 | G = Color.green(pixColor); // (color >> 8) & 0xFF;
22 | B = Color.blue(pixColor); // color & 0xFF
23 | pixel = G - B + G + R;
24 | if (pixel < 0)
25 | pixel = -pixel;
26 | pixel = pixel * R / 256;
27 | if (pixel > 255)
28 | pixel = 255;
29 | R = pixel;
30 |
31 | pixel = B - G + B + R;
32 | if (pixel < 0)
33 | pixel = -pixel;
34 | pixel = pixel * R / 256;
35 | if (pixel > 255)
36 | pixel = 255;
37 | G = pixel;
38 |
39 | pixel = B - G + B + R;
40 | if (pixel < 0)
41 | pixel = -pixel;
42 | pixel = pixel * G / 256;
43 | if (pixel > 255)
44 | pixel = 255;
45 | B = pixel;
46 |
47 | dst[pos] = Color.rgb(R, G, B);
48 | }
49 | }
50 | Bitmap processBitmap = Bitmap.createBitmap(width, height,
51 | Bitmap.Config.RGB_565);
52 | processBitmap.setPixels(dst, 0, width, 0, 0, width, height);
53 | return processBitmap;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/jimageeditdemo/api/EclosionFilter.java:
--------------------------------------------------------------------------------
1 | package com.example.jimageeditdemo.api;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Color;
5 |
6 | public class EclosionFilter {
7 | // 羽化效果
8 | public static Bitmap changeToEclosion(Bitmap bitmap) {
9 | int width = bitmap.getWidth();
10 | int height = bitmap.getHeight();
11 | int dst[] = new int[width * height];
12 | bitmap.getPixels(dst, 0, width, 0, 0, width, height);
13 |
14 | int ratio = width > height ? height*32768/width : width*32768/height;
15 |
16 | int cx = width >> 1;
17 | int cy = height >> 1;
18 | int max = cx * cx + cy * cy;
19 | int min = (int) (max * (1 - 0.5f));
20 | int diff = max - min;
21 |
22 | int R, G, B;
23 | int pos, pixColor;
24 | for (int y = 0; y < height; y++) {
25 | for (int x = 0; x < width; x++) {
26 | pos = y * width + x;
27 | pixColor = dst[pos];
28 | R = Color.red(pixColor);
29 | G = Color.green(pixColor);
30 | B = Color.blue(pixColor);
31 |
32 | int dx = cx - x;
33 | int dy = cy - y;
34 | if (width > height) {
35 | dx = (dx * ratio) >> 15;
36 | } else {
37 | dy = (dy * ratio) >> 15;
38 | }
39 |
40 | int distSq = dx * dx + dy * dy;
41 | float v = ((float) distSq / diff) * 255;
42 | R = (int) (R + (v));
43 | G = (int) (G + (v));
44 | B = (int) (B + (v));
45 | R = (R > 255 ? 255 : (R < 0 ? 0 : R));
46 | G = (G > 255 ? 255 : (G < 0 ? 0 : G));
47 | B = (B > 255 ? 255 : (B < 0 ? 0 : B));
48 |
49 | dst[pos] = Color.rgb(R, G, B);
50 | }
51 | }
52 | Bitmap processBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
53 | processBitmap.setPixels(dst, 0, width, 0, 0, width, height);
54 | return processBitmap;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/jimageeditdemo/api/GrayFilter.java:
--------------------------------------------------------------------------------
1 | package com.example.jimageeditdemo.api;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.ColorMatrix;
6 | import android.graphics.ColorMatrixColorFilter;
7 | import android.graphics.Paint;
8 |
9 | public class GrayFilter {
10 | // 黑白效果函数
11 | public static Bitmap changeToGray(Bitmap bitmap) {
12 |
13 | int width, height;
14 | width = bitmap.getWidth();
15 | height = bitmap.getHeight();
16 |
17 | Bitmap grayBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
18 | Canvas canvas = new Canvas(grayBitmap);
19 | Paint paint = new Paint();
20 | paint.setAntiAlias(true); // 设置抗锯齿
21 |
22 | //test
23 | /*float[] array = {1, 0, 0, 0, 100,
24 | 0, 1, 0, 0, 100,
25 | 0, 0, 1, 0, 0,
26 | 0, 0, 0, 1, 0};
27 | ColorMatrix colorMatrix = new ColorMatrix(array);*/
28 |
29 | ColorMatrix colorMatrix = new ColorMatrix();
30 | colorMatrix.setSaturation(0);
31 |
32 | ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
33 |
34 | paint.setColorFilter(filter);
35 | canvas.drawBitmap(bitmap, 0, 0, paint);
36 |
37 | return grayBitmap;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/jimageeditdemo/api/HahaFilter.java:
--------------------------------------------------------------------------------
1 | package com.example.jimageeditdemo.api;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Color;
5 |
6 | public class HahaFilter {
7 | //哈哈镜效果
8 | public static Bitmap changeToHaha(Bitmap bitmap){
9 | int centerX = bitmap.getWidth() / 2;
10 | int centerY = bitmap.getHeight() / 2;
11 | float radius = Math.min(centerX*2/3, centerY*2/3);
12 | float mutiple = 2.0f;
13 | return changeToHaha(bitmap, radius, centerX, centerY, mutiple);
14 | }
15 |
16 | /**
17 | * @param bitmap 原图bitmap
18 | * @param radius 半径
19 | * @param centerX 圆心x坐标
20 | * @param centerY 圆心y坐标
21 | * @param mutiple 系数
22 | * @return
23 | */
24 | public static Bitmap changeToHaha(Bitmap bitmap, float radius, int centerX, int centerY, float mutiple){
25 | int width = bitmap.getWidth();
26 | int height = bitmap.getHeight();
27 |
28 | int[] src = new int[width*height];
29 | int[] dst = new int[width*height];
30 | bitmap.getPixels(src, 0, width, 0, 0, width, height);
31 |
32 | int x, y, pos, color;
33 | int R, G, B;
34 | int distance;
35 | int src_x, src_y, src_color;
36 | int real_radius = (int)(radius / mutiple);
37 |
38 | for(y=0; y mHighlightViews = new ArrayList();
17 | HighlightView mMotionHighlightView = null;
18 | float mLastX, mLastY;
19 | int mMotionEdge;
20 | //private Bitmap bitmap;
21 | Context mContext;
22 |
23 | @Override
24 | protected void onLayout(boolean changed, int left, int top, int right,
25 | int bottom) {
26 | super.onLayout(changed, left, top, right, bottom);
27 | if (mBitmapDisplayed.getBitmap() != null) {
28 | for (HighlightView hv : mHighlightViews) {
29 | hv.mMatrix.set(getImageMatrix());
30 | hv.invalidate();
31 | if (hv.mIsFocused) {
32 | centerBasedOnHighlightView(hv);
33 | }
34 | }
35 | }
36 | }
37 |
38 | public CropImageView(Context context, AttributeSet attrs) {
39 | super(context, attrs);
40 | }
41 |
42 | @Override
43 | protected void zoomTo(float scale, float centerX, float centerY) {
44 | super.zoomTo(scale, centerX, centerY);
45 | for (HighlightView hv : mHighlightViews) {
46 | hv.mMatrix.set(getImageMatrix());
47 | hv.invalidate();
48 | }
49 | }
50 |
51 | @Override
52 | protected void zoomIn() {
53 | super.zoomIn();
54 | for (HighlightView hv : mHighlightViews) {
55 | hv.mMatrix.set(getImageMatrix());
56 | hv.invalidate();
57 | }
58 | }
59 |
60 | @Override
61 | protected void zoomOut() {
62 | super.zoomOut();
63 | for (HighlightView hv : mHighlightViews) {
64 | hv.mMatrix.set(getImageMatrix());
65 | hv.invalidate();
66 | }
67 | }
68 |
69 | @Override
70 | protected void postTranslate(float deltaX, float deltaY) {
71 | super.postTranslate(deltaX, deltaY);
72 | for (int i = 0; i < mHighlightViews.size(); i++) {
73 | HighlightView hv = mHighlightViews.get(i);
74 | hv.mMatrix.postTranslate(deltaX, deltaY);
75 | hv.invalidate();
76 | }
77 | }
78 |
79 | @Override
80 | public boolean onTouchEvent(MotionEvent event) {
81 | CropActivity cropImage = (CropActivity) mContext;
82 | if (cropImage.mSaving) {
83 | return false;
84 | }
85 |
86 | switch (event.getAction()) {
87 | case MotionEvent.ACTION_DOWN:
88 | for (int i = 0; i < mHighlightViews.size(); i++) {
89 | HighlightView hv = mHighlightViews.get(i);
90 | int edge = hv.getHit(event.getX(), event.getY());
91 | Log.e(TAG, "edge:" + edge);
92 | if (edge != HighlightView.GROW_NONE) {
93 | mMotionEdge = edge;
94 | mMotionHighlightView = hv;
95 | mLastX = event.getX();
96 | mLastY = event.getY();
97 | //shark 此处是区别移动和缩放,还原代码即可打开缩放功能
98 | /*mMotionHighlightView
99 | .setMode((edge == HighlightView.MOVE) ? HighlightView.ModifyMode.Move
100 | : HighlightView.ModifyMode.Grow);*/
101 |
102 | mMotionHighlightView.setMode(HighlightView.ModifyMode.Move);
103 | break;
104 | }
105 | }
106 | break;
107 | case MotionEvent.ACTION_UP:
108 | if (mMotionHighlightView != null) {
109 | centerBasedOnHighlightView(mMotionHighlightView);
110 | mMotionHighlightView.setMode(HighlightView.ModifyMode.None);
111 | }
112 | mMotionHighlightView = null;
113 | break;
114 | case MotionEvent.ACTION_MOVE:
115 | if (mMotionHighlightView != null) {
116 | mMotionHighlightView.handleMotion(mMotionEdge, event.getX()
117 | - mLastX, event.getY() - mLastY);
118 | mLastX = event.getX();
119 | mLastY = event.getY();
120 |
121 | if (true) {
122 | // This section of code is optional. It has some user
123 | // benefit in that moving the crop rectangle against
124 | // the edge of the screen causes scrolling but it means
125 | // that the crop rectangle is no longer fixed under
126 | // the user's finger.
127 | ensureVisible(mMotionHighlightView);
128 | }
129 | }
130 | break;
131 | }
132 |
133 | switch (event.getAction()) {
134 | case MotionEvent.ACTION_UP:
135 | center(true, true);
136 | break;
137 | case MotionEvent.ACTION_MOVE:
138 | // if we're not zoomed then there's no point in even allowing
139 | // the user to move the image around. This call to center puts
140 | // it back to the normalized location (with false meaning don't
141 | // animate).
142 | if (getScale() == 1F) {
143 | center(true, true);
144 | }
145 | break;
146 | }
147 |
148 | return true;
149 | }
150 |
151 | // Pan the displayed image to make sure the cropping rectangle is visible.
152 | private void ensureVisible(HighlightView hv) {
153 | Rect r = hv.mDrawRect;
154 |
155 | int panDeltaX1 = Math.max(0, getLeft() - r.left);
156 | int panDeltaX2 = Math.min(0, getRight() - r.right);
157 |
158 | int panDeltaY1 = Math.max(0, getTop() - r.top);
159 | int panDeltaY2 = Math.min(0, getBottom() - r.bottom);
160 |
161 | int panDeltaX = panDeltaX1 != 0 ? panDeltaX1 : panDeltaX2;
162 | int panDeltaY = panDeltaY1 != 0 ? panDeltaY1 : panDeltaY2;
163 |
164 | if (panDeltaX != 0 || panDeltaY != 0) {
165 | panBy(panDeltaX, panDeltaY);
166 | }
167 | }
168 |
169 | // If the cropping rectangle's size changed significantly, change the
170 | // view's center and scale according to the cropping rectangle.
171 | private void centerBasedOnHighlightView(HighlightView hv) {
172 | Rect drawRect = hv.mDrawRect;
173 |
174 | float width = drawRect.width();
175 | float height = drawRect.height();
176 |
177 | float thisWidth = getWidth();
178 | float thisHeight = getHeight();
179 |
180 | float z1 = thisWidth / width * .6F;
181 | float z2 = thisHeight / height * .6F;
182 |
183 | float zoom = Math.min(z1, z2);
184 | zoom = zoom * this.getScale();
185 | zoom = Math.max(1F, zoom);
186 |
187 | if ((Math.abs(zoom - getScale()) / zoom) > .1) {
188 | float[] coordinates = new float[] { hv.mCropRect.centerX(),
189 | hv.mCropRect.centerY() };
190 | getImageMatrix().mapPoints(coordinates);
191 | zoomTo(zoom, coordinates[0], coordinates[1], 300F);
192 | }
193 |
194 | ensureVisible(hv);
195 | }
196 |
197 | @Override
198 | protected void onDraw(Canvas canvas) {
199 | super.onDraw(canvas);
200 | for (int i = 0; i < mHighlightViews.size(); i++) {
201 | mHighlightViews.get(i).draw(canvas);
202 | }
203 | }
204 |
205 | public void add(HighlightView hv) {
206 | mHighlightViews.add(hv);
207 | invalidate();
208 | }
209 |
210 | public void remove(HighlightView hv){
211 | if(mHighlightViews.contains(hv)){
212 | mHighlightViews.remove(hv);
213 | }
214 | invalidate();
215 | }
216 |
217 |
218 |
219 | }
220 |
221 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/picture/HighlightView.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.picture;
2 |
3 | import com.example.jimageeditdemo.R;
4 |
5 | import android.graphics.Canvas;
6 | import android.graphics.Matrix;
7 | import android.graphics.Paint;
8 | import android.graphics.Path;
9 | import android.graphics.Rect;
10 | import android.graphics.RectF;
11 | import android.graphics.Region;
12 | import android.graphics.drawable.Drawable;
13 | import android.view.View;
14 |
15 | // This class is used by CropImage to display a highlighted cropping rectangle
16 | // overlayed with the image. There are two coordinate spaces in use. One is
17 | // image, another is screen. computeLayout() uses mMatrix to map from image
18 | // space to screen space.
19 | class HighlightView {
20 |
21 | @SuppressWarnings("unused")
22 | private static final String TAG = "HighlightView";
23 | View mContext; // The View displaying the image.
24 |
25 | public static final int GROW_NONE = (1 << 0);
26 | public static final int GROW_LEFT_EDGE = (1 << 1);
27 | public static final int GROW_RIGHT_EDGE = (1 << 2);
28 | public static final int GROW_TOP_EDGE = (1 << 3);
29 | public static final int GROW_BOTTOM_EDGE = (1 << 4);
30 | public static final int MOVE = (1 << 5);
31 |
32 | public HighlightView(View ctx) {
33 | mContext = ctx;
34 | }
35 |
36 | private void init() {
37 | android.content.res.Resources resources = mContext.getResources();
38 | mResizeDrawableWidth =
39 | resources.getDrawable(R.drawable.camera_crop_width);
40 | mResizeDrawableHeight =
41 | resources.getDrawable(R.drawable.camera_crop_height);
42 | mResizeDrawableDiagonal =
43 | resources.getDrawable(R.drawable.indicator_autocrop);
44 | }
45 |
46 | boolean mIsFocused;
47 | boolean mHidden;
48 |
49 | public boolean hasFocus() {
50 | return mIsFocused;
51 | }
52 |
53 | public void setFocus(boolean f) {
54 | mIsFocused = f;
55 | }
56 |
57 | public void setHidden(boolean hidden) {
58 | mHidden = hidden;
59 | }
60 |
61 | protected void draw(Canvas canvas) {
62 | if (mHidden) {
63 | return;
64 | }
65 | canvas.save();
66 | Path path = new Path();
67 | if (!hasFocus()) {
68 |
69 | mOutlinePaint.setColor(0xFF000000);
70 | canvas.drawRect(mDrawRect, mOutlinePaint);
71 | } else {
72 | Rect viewDrawingRect = new Rect();
73 | mContext.getDrawingRect(viewDrawingRect);
74 | if (mCircle) {
75 | float width = mDrawRect.width();
76 | float height = mDrawRect.height();
77 | path.addCircle(mDrawRect.left + (width / 2),
78 | mDrawRect.top + (height / 2),
79 | width / 2,
80 | Path.Direction.CW);
81 | mOutlinePaint.setColor(0xFFEF04D6);
82 | } else {
83 | path.addRect(new RectF(mDrawRect), Path.Direction.CW);
84 | mOutlinePaint.setColor(0xFFFF8A00);
85 | }
86 | canvas.clipPath(path, Region.Op.DIFFERENCE);
87 | canvas.drawRect(viewDrawingRect,
88 | hasFocus() ? mFocusPaint : mNoFocusPaint);
89 |
90 | canvas.restore();
91 | canvas.drawPath(path, mOutlinePaint);
92 |
93 | if (mMode == ModifyMode.Grow) {
94 | if (mCircle) {
95 | int width = mResizeDrawableDiagonal.getIntrinsicWidth();
96 | int height = mResizeDrawableDiagonal.getIntrinsicHeight();
97 |
98 | int d = (int) Math.round(Math.cos(/*45deg*/Math.PI / 4D)
99 | * (mDrawRect.width() / 2D));
100 | int x = mDrawRect.left
101 | + (mDrawRect.width() / 2) + d - width / 2;
102 | int y = mDrawRect.top
103 | + (mDrawRect.height() / 2) - d - height / 2;
104 | mResizeDrawableDiagonal.setBounds(x, y,
105 | x + mResizeDrawableDiagonal.getIntrinsicWidth(),
106 | y + mResizeDrawableDiagonal.getIntrinsicHeight());
107 | mResizeDrawableDiagonal.draw(canvas);
108 | } else {
109 | int left = mDrawRect.left + 1;
110 | int right = mDrawRect.right + 1;
111 | int top = mDrawRect.top + 4;
112 | int bottom = mDrawRect.bottom + 3;
113 |
114 | int widthWidth =
115 | mResizeDrawableWidth.getIntrinsicWidth() / 2;
116 | int widthHeight =
117 | mResizeDrawableWidth.getIntrinsicHeight() / 2;
118 | int heightHeight =
119 | mResizeDrawableHeight.getIntrinsicHeight() / 2;
120 | int heightWidth =
121 | mResizeDrawableHeight.getIntrinsicWidth() / 2;
122 |
123 | int xMiddle = mDrawRect.left
124 | + ((mDrawRect.right - mDrawRect.left) / 2);
125 | int yMiddle = mDrawRect.top
126 | + ((mDrawRect.bottom - mDrawRect.top) / 2);
127 |
128 | mResizeDrawableWidth.setBounds(left - widthWidth,
129 | yMiddle - widthHeight,
130 | left + widthWidth,
131 | yMiddle + widthHeight);
132 | mResizeDrawableWidth.draw(canvas);
133 |
134 | mResizeDrawableWidth.setBounds(right - widthWidth,
135 | yMiddle - widthHeight,
136 | right + widthWidth,
137 | yMiddle + widthHeight);
138 | mResizeDrawableWidth.draw(canvas);
139 |
140 | mResizeDrawableHeight.setBounds(xMiddle - heightWidth,
141 | top - heightHeight,
142 | xMiddle + heightWidth,
143 | top + heightHeight);
144 | mResizeDrawableHeight.draw(canvas);
145 |
146 | mResizeDrawableHeight.setBounds(xMiddle - heightWidth,
147 | bottom - heightHeight,
148 | xMiddle + heightWidth,
149 | bottom + heightHeight);
150 | mResizeDrawableHeight.draw(canvas);
151 | }
152 | }
153 | }
154 | }
155 |
156 | public void setMode(ModifyMode mode) {
157 | if (mode != mMode) {
158 | mMode = mode;
159 | mContext.invalidate();
160 | }
161 | }
162 |
163 | // Determines which edges are hit by touching at (x, y).
164 | //shark All to MOVE
165 | public int getHit(float x, float y) {
166 | Rect r = computeLayout();
167 | final float hysteresis = 20F;
168 | int retval = GROW_NONE;
169 |
170 | if (mCircle) {
171 | float distX = x - r.centerX();
172 | float distY = y - r.centerY();
173 | int distanceFromCenter =
174 | (int) Math.sqrt(distX * distX + distY * distY);
175 | int radius = mDrawRect.width() / 2;
176 | int delta = distanceFromCenter - radius;
177 | if (Math.abs(delta) <= hysteresis) {
178 | if (Math.abs(distY) > Math.abs(distX)) {
179 | if (distY < 0) {
180 | retval = MOVE;
181 | } else {
182 | retval = MOVE;
183 | }
184 | } else {
185 | if (distX < 0) {
186 | retval = MOVE;
187 | } else {
188 | retval = MOVE;
189 | }
190 | }
191 | } else if (distanceFromCenter < radius) {
192 | retval = MOVE;
193 | } else {
194 | retval = GROW_NONE;
195 | }
196 | } else {
197 | // verticalCheck makes sure the position is between the top and
198 | // the bottom edge (with some tolerance). Similar for horizCheck.
199 | boolean verticalCheck = (y >= r.top - hysteresis)
200 | && (y < r.bottom + hysteresis);
201 | boolean horizCheck = (x >= r.left - hysteresis)
202 | && (x < r.right + hysteresis);
203 |
204 | // Check whether the position is near some edge(s).
205 | if ((Math.abs(r.left - x) < hysteresis) && verticalCheck) {
206 | retval |= MOVE;
207 | }
208 | if ((Math.abs(r.right - x) < hysteresis) && verticalCheck) {
209 | retval |= MOVE;
210 | }
211 | if ((Math.abs(r.top - y) < hysteresis) && horizCheck) {
212 | retval |= MOVE;
213 | }
214 | if ((Math.abs(r.bottom - y) < hysteresis) && horizCheck) {
215 | retval |= MOVE;
216 | }
217 |
218 | // Not near any edge but inside the rectangle: move.
219 | if (retval == GROW_NONE && r.contains((int) x, (int) y)) {
220 | retval = MOVE;
221 | }
222 | }
223 | return retval;
224 | }
225 |
226 | // Handles motion (dx, dy) in screen space.
227 | // The "edge" parameter specifies which edges the user is dragging.
228 | void handleMotion(int edge, float dx, float dy) {
229 | Rect r = computeLayout();
230 | if (edge == GROW_NONE) {
231 | return;
232 | } else if (edge == MOVE) {
233 | // Convert to image space before sending to moveBy().
234 | moveBy(dx * (mCropRect.width() / r.width()),
235 | dy * (mCropRect.height() / r.height()));
236 | } else {
237 | if (((GROW_LEFT_EDGE | GROW_RIGHT_EDGE) & edge) == 0) {
238 | dx = 0;
239 | }
240 |
241 | if (((GROW_TOP_EDGE | GROW_BOTTOM_EDGE) & edge) == 0) {
242 | dy = 0;
243 | }
244 |
245 | // Convert to image space before sending to growBy().
246 | float xDelta = dx * (mCropRect.width() / r.width());
247 | float yDelta = dy * (mCropRect.height() / r.height());
248 | growBy((((edge & GROW_LEFT_EDGE) != 0) ? -1 : 1) * xDelta,
249 | (((edge & GROW_TOP_EDGE) != 0) ? -1 : 1) * yDelta);
250 | }
251 | }
252 |
253 | // Grows the cropping rectange by (dx, dy) in image space.
254 | void moveBy(float dx, float dy) {
255 | Rect invalRect = new Rect(mDrawRect);
256 |
257 | mCropRect.offset(dx, dy);
258 |
259 | // Put the cropping rectangle inside image rectangle.
260 | mCropRect.offset(
261 | Math.max(0, mImageRect.left - mCropRect.left),
262 | Math.max(0, mImageRect.top - mCropRect.top));
263 |
264 | mCropRect.offset(
265 | Math.min(0, mImageRect.right - mCropRect.right),
266 | Math.min(0, mImageRect.bottom - mCropRect.bottom));
267 |
268 | mDrawRect = computeLayout();
269 | invalRect.union(mDrawRect);
270 | invalRect.inset(-10, -10);
271 | mContext.invalidate(invalRect);
272 | }
273 |
274 | // Grows the cropping rectange by (dx, dy) in image space.
275 | void growBy(float dx, float dy) {
276 | if (mMaintainAspectRatio) {
277 | if (dx != 0) {
278 | dy = dx / mInitialAspectRatio;
279 | } else if (dy != 0) {
280 | dx = dy * mInitialAspectRatio;
281 | }
282 | }
283 |
284 | // Don't let the cropping rectangle grow too fast.
285 | // Grow at most half of the difference between the image rectangle and
286 | // the cropping rectangle.
287 | RectF r = new RectF(mCropRect);
288 | if (dx > 0F && r.width() + 2 * dx > mImageRect.width()) {
289 | float adjustment = (mImageRect.width() - r.width()) / 2F;
290 | dx = adjustment;
291 | if (mMaintainAspectRatio) {
292 | dy = dx / mInitialAspectRatio;
293 | }
294 | }
295 | if (dy > 0F && r.height() + 2 * dy > mImageRect.height()) {
296 | float adjustment = (mImageRect.height() - r.height()) / 2F;
297 | dy = adjustment;
298 | if (mMaintainAspectRatio) {
299 | dx = dy * mInitialAspectRatio;
300 | }
301 | }
302 |
303 | r.inset(-dx, -dy);
304 |
305 | // Don't let the cropping rectangle shrink too fast.
306 | final float widthCap = 25F;
307 | if (r.width() < widthCap) {
308 | r.inset(-(widthCap - r.width()) / 2F, 0F);
309 | }
310 | float heightCap = mMaintainAspectRatio
311 | ? (widthCap / mInitialAspectRatio)
312 | : widthCap;
313 | if (r.height() < heightCap) {
314 | r.inset(0F, -(heightCap - r.height()) / 2F);
315 | }
316 |
317 | // Put the cropping rectangle inside the image rectangle.
318 | if (r.left < mImageRect.left) {
319 | r.offset(mImageRect.left - r.left, 0F);
320 | } else if (r.right > mImageRect.right) {
321 | r.offset(-(r.right - mImageRect.right), 0);
322 | }
323 | if (r.top < mImageRect.top) {
324 | r.offset(0F, mImageRect.top - r.top);
325 | } else if (r.bottom > mImageRect.bottom) {
326 | r.offset(0F, -(r.bottom - mImageRect.bottom));
327 | }
328 |
329 | mCropRect.set(r);
330 | mDrawRect = computeLayout();
331 | mContext.invalidate();
332 | }
333 |
334 | // Returns the cropping rectangle in image space.
335 | public Rect getCropRect() {
336 | return new Rect((int) mCropRect.left, (int) mCropRect.top,
337 | (int) mCropRect.right, (int) mCropRect.bottom);
338 | }
339 |
340 | // Maps the cropping rectangle from image space to screen space.
341 | private Rect computeLayout() {
342 | RectF r = new RectF(mCropRect.left, mCropRect.top,
343 | mCropRect.right, mCropRect.bottom);
344 | mMatrix.mapRect(r);
345 |
346 | return new Rect(Math.round(r.left), Math.round(r.top),
347 | Math.round(r.right), Math.round(r.bottom));
348 | }
349 |
350 | public void invalidate() {
351 | mDrawRect = computeLayout();
352 | }
353 |
354 | public void setup(Matrix m, Rect imageRect, RectF cropRect, boolean circle,
355 | boolean maintainAspectRatio) {
356 | if (circle) {
357 | maintainAspectRatio = true;
358 | }
359 | mMatrix = new Matrix(m);
360 |
361 | mCropRect = cropRect;
362 | mImageRect = new RectF(imageRect);
363 | mMaintainAspectRatio = maintainAspectRatio;
364 | mCircle = circle;
365 |
366 | mInitialAspectRatio = mCropRect.width() / mCropRect.height();
367 | mDrawRect = computeLayout();
368 |
369 | mFocusPaint.setARGB(125, 50, 50, 50);
370 | mNoFocusPaint.setARGB(125, 50, 50, 50);
371 | mOutlinePaint.setStrokeWidth(3F);
372 | mOutlinePaint.setStyle(Paint.Style.STROKE);
373 | mOutlinePaint.setAntiAlias(true);
374 |
375 | mMode = ModifyMode.None;
376 | init();
377 | }
378 |
379 | enum ModifyMode { None, Move, Grow }
380 |
381 | private ModifyMode mMode = ModifyMode.None;
382 |
383 | Rect mDrawRect; // in screen space
384 | private RectF mImageRect; // in image space
385 | RectF mCropRect; // in image space
386 | Matrix mMatrix;
387 |
388 | private boolean mMaintainAspectRatio = false;
389 | private float mInitialAspectRatio;
390 | private boolean mCircle = false;
391 |
392 | private Drawable mResizeDrawableWidth;
393 | private Drawable mResizeDrawableHeight;
394 | private Drawable mResizeDrawableDiagonal;
395 |
396 | private final Paint mFocusPaint = new Paint();
397 | private final Paint mNoFocusPaint = new Paint();
398 | private final Paint mOutlinePaint = new Paint();
399 | }
400 |
401 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/picture/ImageViewTouchBase.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.picture;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Matrix;
6 | import android.graphics.RectF;
7 | import android.graphics.drawable.Drawable;
8 | import android.os.Handler;
9 | import android.util.AttributeSet;
10 | import android.util.Log;
11 | import android.view.KeyEvent;
12 | import android.widget.ImageView;
13 |
14 | abstract class ImageViewTouchBase extends ImageView {
15 |
16 | @SuppressWarnings("unused")
17 | private static final String TAG = "ImageViewTouchBase";
18 |
19 | // This is the base transformation which is used to show the image
20 | // initially. The current computation for this shows the image in
21 | // it's entirety, letterboxing as needed. One could choose to
22 | // show the image as cropped instead.
23 | //
24 | // This matrix is recomputed when we go from the thumbnail image to
25 | // the full size image.
26 | protected Matrix mBaseMatrix = new Matrix();
27 |
28 | // This is the supplementary transformation which reflects what
29 | // the user has done in terms of zooming and panning.
30 | //
31 | // This matrix remains the same when we go from the thumbnail image
32 | // to the full size image.
33 | protected Matrix mSuppMatrix = new Matrix();
34 |
35 | // This is the final matrix which is computed as the concatentation
36 | // of the base matrix and the supplementary matrix.
37 | private final Matrix mDisplayMatrix = new Matrix();
38 |
39 | // Temporary buffer used for getting the values out of a matrix.
40 | private final float[] mMatrixValues = new float[9];
41 |
42 | // The current bitmap being displayed.
43 | protected final RotateBitmap mBitmapDisplayed = new RotateBitmap(null);
44 |
45 | int mThisWidth = -1, mThisHeight = -1;
46 |
47 | float mMaxZoom;
48 |
49 | // ImageViewTouchBase will pass a Bitmap to the Recycler if it has finished
50 | // its use of that Bitmap.
51 | public interface Recycler {
52 | public void recycle(Bitmap b);
53 | }
54 |
55 | public void setRecycler(Recycler r) {
56 | mRecycler = r;
57 | }
58 |
59 | private Recycler mRecycler;
60 |
61 | @Override
62 | protected void onLayout(boolean changed, int left, int top,
63 | int right, int bottom) {
64 | super.onLayout(changed, left, top, right, bottom);
65 | mThisWidth = right - left;
66 | mThisHeight = bottom - top;
67 | Runnable r = mOnLayoutRunnable;
68 | if (r != null) {
69 | mOnLayoutRunnable = null;
70 | r.run();
71 | }
72 | if (mBitmapDisplayed.getBitmap() != null) {
73 | getProperBaseMatrix(mBitmapDisplayed, mBaseMatrix);
74 | setImageMatrix(getImageViewMatrix());
75 | }
76 | }
77 |
78 | @Override
79 | public boolean onKeyDown(int keyCode, KeyEvent event) {
80 | if (keyCode == KeyEvent.KEYCODE_BACK
81 | && event.getRepeatCount() == 0) {
82 | event.startTracking();
83 | return true;
84 | }
85 | return super.onKeyDown(keyCode, event);
86 | }
87 |
88 | @Override
89 | public boolean onKeyUp(int keyCode, KeyEvent event) {
90 | Log.d(TAG, "onKeyUp");
91 | if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
92 | && !event.isCanceled()) {
93 | if (getScale() > 1.0f) {
94 | // If we're zoomed in, pressing Back jumps out to show the
95 | // entire image, otherwise Back returns the user to the gallery.
96 | zoomTo(1.0f);
97 | return true;
98 | }
99 | }
100 | return super.onKeyUp(keyCode, event);
101 | }
102 |
103 | protected Handler mHandler = new Handler();
104 |
105 | @Override
106 | public void setImageBitmap(Bitmap bitmap) {
107 | setImageBitmap(bitmap, 0);
108 | }
109 |
110 | protected void setImageBitmap(Bitmap bitmap, int rotation) {
111 | super.setImageBitmap(bitmap);
112 |
113 | Drawable d = getDrawable();
114 | if (d != null) {
115 | d.setDither(true);
116 | }
117 |
118 | Bitmap old = mBitmapDisplayed.getBitmap();
119 | mBitmapDisplayed.setBitmap(bitmap);
120 | mBitmapDisplayed.setRotation(rotation);
121 |
122 | if (old != null && old != bitmap && mRecycler != null) {
123 | mRecycler.recycle(old);
124 | }
125 | }
126 |
127 | public void clear() {
128 | setImageBitmapResetBase(null, true);
129 | }
130 |
131 | private Runnable mOnLayoutRunnable = null;
132 |
133 | // This function changes bitmap, reset base matrix according to the size
134 | // of the bitmap, and optionally reset the supplementary matrix.
135 | public void setImageBitmapResetBase(final Bitmap bitmap,
136 | final boolean resetSupp) {
137 | setImageRotateBitmapResetBase(new RotateBitmap(bitmap), resetSupp);
138 | }
139 |
140 | public void setImageRotateBitmapResetBase(final RotateBitmap bitmap,
141 | final boolean resetSupp) {
142 |
143 | final int viewWidth = getWidth();
144 |
145 | if (viewWidth <= 0) {
146 | mOnLayoutRunnable = new Runnable() {
147 | public void run() {
148 | setImageRotateBitmapResetBase(bitmap, resetSupp);
149 | }
150 | };
151 | return;
152 | }
153 | //setImageBitmap(null);
154 | if (bitmap.getBitmap() != null) {
155 |
156 | getProperBaseMatrix(bitmap, mBaseMatrix);
157 | setImageBitmap(bitmap.getBitmap(), bitmap.getRotation());
158 |
159 | } else {
160 | mBaseMatrix.reset();
161 | setImageBitmap(null);
162 | }
163 |
164 | if (resetSupp) {
165 | mSuppMatrix.reset();
166 | }
167 | setImageMatrix(getImageViewMatrix());
168 | mMaxZoom = maxZoom();
169 | }
170 | // Center as much as possible in one or both axis. Centering is
171 | // defined as follows: if the image is scaled down below the
172 | // view's dimensions then center it (literally). If the image
173 | // is scaled larger than the view and is translated out of view
174 | // then translate it back into view (i.e. eliminate black bars).
175 | protected void center(boolean horizontal, boolean vertical) {
176 | Log.d(TAG, "center");
177 | if (mBitmapDisplayed.getBitmap() == null) {
178 | return;
179 | }
180 |
181 | Matrix m = getImageViewMatrix();
182 |
183 | RectF rect = new RectF(0, 0,
184 | mBitmapDisplayed.getBitmap().getWidth(),
185 | mBitmapDisplayed.getBitmap().getHeight());
186 |
187 | m.mapRect(rect);
188 |
189 | float height = rect.height();
190 | float width = rect.width();
191 |
192 | float deltaX = 0, deltaY = 0;
193 |
194 | if (vertical) {
195 | int viewHeight = getHeight();
196 | if (height < viewHeight) {
197 | deltaY = (viewHeight - height) / 2 - rect.top;
198 | } else if (rect.top > 0) {
199 | deltaY = -rect.top;
200 | } else if (rect.bottom < viewHeight) {
201 | deltaY = getHeight() - rect.bottom;
202 | }
203 | }
204 |
205 | if (horizontal) {
206 | int viewWidth = getWidth();
207 | if (width < viewWidth) {
208 | deltaX = (viewWidth - width) / 2 - rect.left;
209 | } else if (rect.left > 0) {
210 | deltaX = -rect.left;
211 | } else if (rect.right < viewWidth) {
212 | deltaX = viewWidth - rect.right;
213 | }
214 | }
215 |
216 | postTranslate(deltaX, deltaY);
217 | setImageMatrix(getImageViewMatrix());
218 | }
219 |
220 | public ImageViewTouchBase(Context context) {
221 | super(context);
222 | init();
223 | }
224 |
225 | public ImageViewTouchBase(Context context, AttributeSet attrs) {
226 | super(context, attrs);
227 | init();
228 | }
229 |
230 | private void init() {
231 | setScaleType(ImageView.ScaleType.MATRIX);
232 | }
233 |
234 | protected float getValue(Matrix matrix, int whichValue) {
235 | matrix.getValues(mMatrixValues);
236 | return mMatrixValues[whichValue];
237 | }
238 |
239 | // Get the scale factor out of the matrix.
240 | protected float getScale(Matrix matrix) {
241 | Log.d(TAG, "getScale(Matrix matrix)");
242 | return getValue(matrix, Matrix.MSCALE_X);
243 | }
244 |
245 | protected float getScale() {
246 | Log.d(TAG, "getScale");
247 | return getScale(mSuppMatrix);
248 | }
249 |
250 | // Setup the base matrix so that the image is centered and scaled properly.
251 | private void getProperBaseMatrix(RotateBitmap bitmap, Matrix matrix) {
252 | Log.d(TAG, "getProperBaseMatrix");
253 | float viewWidth = getWidth();
254 | float viewHeight = getHeight();
255 |
256 | float w = bitmap.getWidth();
257 | float h = bitmap.getHeight();
258 | matrix.reset();
259 |
260 | // We limit up-scaling to 3x otherwise the result may look bad if it's
261 | // a small icon.
262 | float widthScale = Math.min(viewWidth / w, 3.0f);
263 | float heightScale = Math.min(viewHeight / h, 3.0f);
264 | float scale = Math.min(widthScale, heightScale);
265 |
266 | matrix.postConcat(bitmap.getRotateMatrix());
267 | matrix.postScale(scale, scale);
268 |
269 | matrix.postTranslate(
270 | (viewWidth - w * scale) / 2F,
271 | (viewHeight - h * scale) / 2F);
272 | }
273 |
274 | // Combine the base matrix and the supp matrix to make the final matrix.
275 | protected Matrix getImageViewMatrix() {
276 | // The final matrix is computed as the concatentation of the base matrix
277 | // and the supplementary matrix.
278 | Log.d(TAG, "getImageViewMatrix");
279 | mDisplayMatrix.set(mBaseMatrix);
280 | mDisplayMatrix.postConcat(mSuppMatrix);
281 | return mDisplayMatrix;
282 | }
283 |
284 | static final float SCALE_RATE = 1.25F;
285 |
286 | // Sets the maximum zoom, which is a scale relative to the base matrix. It
287 | // is calculated to show the image at 400% zoom regardless of screen or
288 | // image orientation. If in the future we decode the full 3 megapixel image,
289 | // rather than the current 1024x768, this should be changed down to 200%.
290 | protected float maxZoom() {
291 | if (mBitmapDisplayed.getBitmap() == null) {
292 | return 1F;
293 | }
294 |
295 | float fw = (float) mBitmapDisplayed.getWidth() / (float) mThisWidth;
296 | float fh = (float) mBitmapDisplayed.getHeight() / (float) mThisHeight;
297 | float max = Math.max(fw, fh) * 4;
298 | return max;
299 | }
300 |
301 | protected void zoomTo(float scale, float centerX, float centerY) {
302 | if (scale > mMaxZoom) {
303 | scale = mMaxZoom;
304 | }
305 |
306 | float oldScale = getScale();
307 | float deltaScale = scale / oldScale;
308 |
309 | mSuppMatrix.postScale(deltaScale, deltaScale, centerX, centerY);
310 | setImageMatrix(getImageViewMatrix());
311 | center(true, true);
312 | }
313 |
314 | protected void zoomTo(final float scale, final float centerX,
315 | final float centerY, final float durationMs) {
316 | final float incrementPerMs = (scale - getScale()) / durationMs;
317 | final float oldScale = getScale();
318 | final long startTime = System.currentTimeMillis();
319 |
320 | mHandler.post(new Runnable() {
321 | public void run() {
322 | long now = System.currentTimeMillis();
323 | float currentMs = Math.min(durationMs, now - startTime);
324 | float target = oldScale + (incrementPerMs * currentMs);
325 | zoomTo(target, centerX, centerY);
326 |
327 | if (currentMs < durationMs) {
328 | mHandler.post(this);
329 | }
330 | }
331 | });
332 | }
333 |
334 | protected void zoomTo(float scale) {
335 | float cx = getWidth() / 2F;
336 | float cy = getHeight() / 2F;
337 |
338 | zoomTo(scale, cx, cy);
339 | }
340 |
341 | protected void zoomToPoint(float scale, float pointX, float pointY) {
342 | float cx = getWidth() / 2F;
343 | float cy = getHeight() / 2F;
344 |
345 | panBy(cx - pointX, cy - pointY);
346 | zoomTo(scale, cx, cy);
347 | }
348 |
349 | protected void zoomIn() {
350 | zoomIn(SCALE_RATE);
351 | }
352 |
353 | protected void zoomOut() {
354 | zoomOut(SCALE_RATE);
355 | }
356 |
357 | protected void zoomIn(float rate) {
358 | if (getScale() >= mMaxZoom) {
359 | return; // Don't let the user zoom into the molecular level.
360 | }
361 | if (mBitmapDisplayed.getBitmap() == null) {
362 | return;
363 | }
364 |
365 | float cx = getWidth() / 2F;
366 | float cy = getHeight() / 2F;
367 |
368 | mSuppMatrix.postScale(rate, rate, cx, cy);
369 | setImageMatrix(getImageViewMatrix());
370 | }
371 |
372 | protected void zoomOut(float rate) {
373 | if (mBitmapDisplayed.getBitmap() == null) {
374 | return;
375 | }
376 |
377 | float cx = getWidth() / 2F;
378 | float cy = getHeight() / 2F;
379 |
380 | // Zoom out to at most 1x.
381 | Matrix tmp = new Matrix(mSuppMatrix);
382 | tmp.postScale(1F / rate, 1F / rate, cx, cy);
383 |
384 | if (getScale(tmp) < 1F) {
385 | mSuppMatrix.setScale(1F, 1F, cx, cy);
386 | } else {
387 | mSuppMatrix.postScale(1F / rate, 1F / rate, cx, cy);
388 | }
389 | setImageMatrix(getImageViewMatrix());
390 | center(true, true);
391 | }
392 |
393 | protected void postTranslate(float dx, float dy) {
394 | mSuppMatrix.postTranslate(dx, dy);
395 | }
396 |
397 | protected void panBy(float dx, float dy) {
398 | postTranslate(dx, dy);
399 | setImageMatrix(getImageViewMatrix());
400 | }
401 | }
402 |
403 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/picture/MonitoredActivity.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.picture;
2 |
3 | import java.util.ArrayList;
4 |
5 | import android.app.Activity;
6 | import android.os.Bundle;
7 |
8 | public class MonitoredActivity extends Activity {
9 |
10 | private final ArrayList mListeners =
11 | new ArrayList();
12 |
13 | public static interface LifeCycleListener {
14 | public void onActivityCreated(MonitoredActivity activity);
15 | public void onActivityDestroyed(MonitoredActivity activity);
16 | public void onActivityStarted(MonitoredActivity activity);
17 | public void onActivityStopped(MonitoredActivity activity);
18 | }
19 |
20 | public static class LifeCycleAdapter implements LifeCycleListener {
21 | public void onActivityCreated(MonitoredActivity activity) {
22 | }
23 |
24 | public void onActivityDestroyed(MonitoredActivity activity) {
25 | }
26 |
27 | public void onActivityStarted(MonitoredActivity activity) {
28 | }
29 |
30 | public void onActivityStopped(MonitoredActivity activity) {
31 | }
32 | }
33 |
34 | public void addLifeCycleListener(LifeCycleListener listener) {
35 | if (mListeners.contains(listener)) return;
36 | mListeners.add(listener);
37 | }
38 |
39 | public void removeLifeCycleListener(LifeCycleListener listener) {
40 | mListeners.remove(listener);
41 | }
42 |
43 | @Override
44 | protected void onCreate(Bundle savedInstanceState) {
45 | super.onCreate(savedInstanceState);
46 | for (LifeCycleListener listener : mListeners) {
47 | listener.onActivityCreated(this);
48 | }
49 | }
50 |
51 | @Override
52 | protected void onDestroy() {
53 | super.onDestroy();
54 | for (LifeCycleListener listener : mListeners) {
55 | listener.onActivityDestroyed(this);
56 | }
57 | }
58 |
59 | @Override
60 | protected void onStart() {
61 | super.onStart();
62 | for (LifeCycleListener listener : mListeners) {
63 | listener.onActivityStarted(this);
64 | }
65 | }
66 |
67 | @Override
68 | protected void onStop() {
69 | super.onStop();
70 | for (LifeCycleListener listener : mListeners) {
71 | listener.onActivityStopped(this);
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/picture/RotateBitmap.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.picture;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Matrix;
5 |
6 | public class RotateBitmap {
7 | public static final String TAG = "RotateBitmap";
8 | private Bitmap mBitmap;
9 | private int mRotation;
10 |
11 | public RotateBitmap(){
12 | mRotation = 0;
13 | }
14 | public RotateBitmap(Bitmap bitmap) {
15 | mBitmap = bitmap;
16 | mRotation = 0;
17 | }
18 |
19 | public RotateBitmap(Bitmap bitmap, int rotation) {
20 | mBitmap = bitmap;
21 | mRotation = rotation % 360;
22 | }
23 |
24 | public void setRotation(int rotation) {
25 | mRotation = rotation;
26 | }
27 |
28 | public int getRotation() {
29 | return mRotation;
30 | }
31 |
32 | public Bitmap getBitmap() {
33 | return mBitmap;
34 | }
35 |
36 | public void setBitmap(Bitmap bitmap) {
37 | mBitmap = bitmap;
38 | }
39 |
40 | public Matrix getRotateMatrix() {
41 | // By default this is an identity matrix.
42 | Matrix matrix = new Matrix();
43 | if (mRotation != 0) {
44 | // We want to do the rotation at origin, but since the bounding
45 | // rectangle will be changed after rotation, so the delta values
46 | // are based on old & new width/height respectively.
47 | int cx = mBitmap.getWidth() / 2;
48 | int cy = mBitmap.getHeight() / 2;
49 | matrix.preTranslate(-cx, -cy);
50 | matrix.postRotate(mRotation);
51 | matrix.postTranslate(getWidth() / 2, getHeight() / 2);
52 | }
53 | return matrix;
54 | }
55 |
56 | public boolean isOrientationChanged() {
57 | return (mRotation / 90) % 2 != 0;
58 | }
59 |
60 | public int getHeight() {
61 | if (isOrientationChanged()) {
62 | return mBitmap.getWidth();
63 | } else {
64 | return mBitmap.getHeight();
65 | }
66 | }
67 |
68 | public int getWidth() {
69 | if (isOrientationChanged()) {
70 | return mBitmap.getHeight();
71 | } else {
72 | return mBitmap.getWidth();
73 | }
74 | }
75 |
76 | public void recycle() {
77 | if (mBitmap != null) {
78 | mBitmap.recycle();
79 | mBitmap = null;
80 | }
81 | }
82 | }
83 |
84 |
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/picture/TakePicActivity.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.picture;
2 |
3 | import android.app.Activity;
4 | import android.app.AlertDialog;
5 | import android.content.DialogInterface;
6 | import android.content.Intent;
7 | import android.net.Uri;
8 | import android.os.Bundle;
9 | import android.os.Environment;
10 | import android.view.Display;
11 | import android.view.View;
12 | import android.view.View.OnClickListener;
13 | import android.widget.Button;
14 |
15 | import com.example.jimageeditdemo.R;
16 | import com.pmmq.pmmqproject.config.Constant;
17 | import com.pmmq.pmmqproject.ui.tag.PreViewActivity;
18 | import com.pmmq.pmmqproject.util.FileUtils;
19 | import com.pmmq.pmmqproject.util.Logger;
20 |
21 | import java.io.File;
22 | import java.text.SimpleDateFormat;
23 | import java.util.Date;
24 |
25 | /**
26 | * @author shark
27 | * @ClassName: TakePicActivity
28 | * @Description: 照片选取
29 | * @date 2014年11月26日 上午10:53:58
30 | */
31 | public class TakePicActivity extends Activity implements OnClickListener {
32 | private String TAG = "TakePicActivity";
33 | //照片存储地址,这个照片没有添加标签
34 | public static final String IMAGE_SAVE = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/Camera";
35 | public final static String IMAGE_URI = "iamge_uri";
36 | public final static String CROP_IMAGE_URI = "crop_image_uri";
37 |
38 | public Uri mCameraImageUri;
39 | // public Uri mImageUri;
40 |
41 | public final static int REQ_CODE_GALLERY = 201;
42 | public final static int REQ_CODE_CAMERA = 203;
43 | public final static int REQ_CODE_PHOTO_CROP = 102;
44 |
45 | private Button mSelectBtn;
46 | // private ImageView mImageView;
47 |
48 | @Override
49 | protected void onCreate(Bundle savedInstanceState) {
50 | super.onCreate(savedInstanceState);
51 | setContentView(R.layout.activity_take_pic);
52 |
53 |
54 | //创建App缓存文件夹
55 | Constant.CACHEPATH = new FileUtils(this).makeAppDir();
56 | Logger.d(TAG, "Constant.CACHEPATH = " + Constant.CACHEPATH);
57 |
58 | Display display = getWindowManager().getDefaultDisplay();
59 | Constant.displayWidth = display.getWidth();
60 | Constant.displayHeight = display.getHeight();
61 | Logger.d(TAG, "Constant.displayWidth = " + Constant.displayWidth + "-- Constant.displayHeight = " + Constant.displayHeight);
62 | Constant.scale = getResources().getDisplayMetrics().density;
63 | Logger.d(TAG, "scale = " + Constant.scale);
64 |
65 | initViews();
66 | }
67 |
68 | private void initViews() {
69 | // mImageView = (ImageView)findViewById(R.id.jimageview);
70 | mSelectBtn = (Button) findViewById(R.id.selectpic);
71 | mSelectBtn.setOnClickListener(this);
72 | }
73 |
74 | @Override
75 | public void onClick(View v) {
76 | // TODO Auto-generated method stub
77 | switch (v.getId()) {
78 | case R.id.selectpic:
79 | showPostMenu();
80 | break;
81 | default:
82 | break;
83 | }
84 | }
85 |
86 | //显示出选择菜单
87 | private void showPostMenu() {
88 | new AlertDialog.Builder(this).setItems(new String[]{"拍照", "相册"}, new DialogInterface.OnClickListener() {
89 | public void onClick(DialogInterface paramDialogInterface, int paramInt) {
90 | if (paramInt == 0) {
91 | Intent localIntent1 = new Intent("android.media.action.IMAGE_CAPTURE");
92 | //设置相机图片的输出路径
93 | mCameraImageUri = Uri.fromFile(new File(IMAGE_SAVE, new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date()) + ".jpg"));
94 | localIntent1.putExtra("output", mCameraImageUri);
95 | Logger.d(TAG, "mCameraImageUri:" + mCameraImageUri);
96 | TakePicActivity.this.startActivityForResult(localIntent1, REQ_CODE_CAMERA);
97 | return;
98 | } else {
99 | Intent localIntent2 = new Intent();
100 | localIntent2.setType("image/*");
101 | localIntent2.setAction("android.intent.action.GET_CONTENT");
102 | TakePicActivity.this.startActivityForResult(Intent.createChooser(localIntent2, "选择照片"), REQ_CODE_GALLERY);
103 | }
104 | }
105 | }).show();
106 | }
107 |
108 | @Override
109 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
110 | // TODO Auto-generated method stub
111 | super.onActivityResult(requestCode, resultCode, data);
112 | Logger.d(TAG, "onActivityResult ");
113 |
114 | if (resultCode == RESULT_OK) {
115 | if (requestCode == REQ_CODE_GALLERY) {
116 | // 从相册返回
117 | Uri localUri = data.getData();
118 | if (localUri == null) {
119 | return;
120 | }
121 | readLocalImage(localUri);
122 | } else if (requestCode == REQ_CODE_CAMERA) {
123 | // 从相机返回,从设置相机图片的输出路径中提取数据
124 | Logger.d(TAG, "mCameraImageUri:" + mCameraImageUri);
125 | readLocalImage(mCameraImageUri);
126 |
127 | } else if (requestCode == REQ_CODE_PHOTO_CROP) {
128 | String imagePath = data.getStringExtra("tag_image_path");
129 | Intent intent = new Intent(this, PreViewActivity.class);
130 | intent.putExtra("tag_image_path", imagePath);
131 | startActivity(intent);
132 |
133 | }
134 | }
135 | }
136 |
137 | //选择照片后进行图片裁剪
138 | private void readLocalImage(Uri uri) {
139 | if (uri != null) {
140 | startPhotoCrop(uri, null, REQ_CODE_PHOTO_CROP); // 图片裁剪
141 | }
142 | }
143 |
144 | /**
145 | * 开始裁剪
146 | *
147 | * @param uri
148 | * @param duplicatePath
149 | * @param reqCode
150 | * @return void
151 | * @Title: startPhotoCrop
152 | * @date 2012-12-12 上午11:15:38
153 | */
154 | private void startPhotoCrop(Uri uri, String duplicatePath, int reqCode) {
155 |
156 |
157 | // Uri duplicateUri = preCrop(uri,duplicatePath);
158 |
159 | Intent intent = new Intent(this, CropActivity.class);//跳转到裁剪界面
160 | intent.putExtra(IMAGE_URI, uri);
161 | startActivityForResult(intent, reqCode);
162 |
163 | /**intent.setDataAndType(uri, "image/*");
164 | intent.putExtra("crop", "true");
165 | intent.putExtra("outputFormat", "JPEG");
166 | // aspectX aspectY 是宽高的比例
167 | intent.putExtra("aspectX", 1);
168 | intent.putExtra("aspectY", 1);
169 | // outputX outputY 是裁剪图片宽高
170 | intent.putExtra("outputX", reqCode == REQ_CODE_BG_CROP ? BG_CROP_WIDTH
171 | : AVATAR_CROP_WIDTH);
172 | intent.putExtra("outputY", reqCode == REQ_CODE_BG_CROP ? BG_CROP_HEIGHT
173 | : AVATAR_CROP_HEIGHT);
174 | intent.putExtra(MediaStore.EXTRA_OUTPUT, duplicateUri);
175 | intent.putExtra("return-data", true);*/
176 |
177 | }
178 |
179 | }
180 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/picture/TouchImageView.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.picture;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Bitmap.Config;
6 | import android.graphics.Canvas;
7 | import android.graphics.Matrix;
8 | import android.graphics.PointF;
9 | import android.util.DisplayMetrics;
10 | import android.view.MotionEvent;
11 | import android.widget.ImageView;
12 |
13 | /**
14 | * 可移动、缩放、旋转的ImageView
15 | *
16 | * @author
17 | * @ClassName: TouchImageView
18 | * @Description: TODO
19 | * @date 2014年11月28日 下午4:52:44
20 | */
21 | public class TouchImageView extends ImageView {
22 |
23 | float x_down = 0;
24 | float y_down = 0;
25 | PointF start = new PointF();
26 | PointF mid = new PointF();
27 | float oldDist = 1f;
28 | float oldRotation = 0;
29 | Matrix matrix = new Matrix();
30 | Matrix matrix1 = new Matrix();
31 | Matrix savedMatrix = new Matrix();
32 |
33 | private static final int NONE = 0;
34 | private static final int DRAG = 1;
35 | private static final int ZOOM = 2;
36 | int mode = NONE;
37 |
38 | boolean matrixCheck = false;
39 |
40 | int widthScreen;
41 | int heightScreen;
42 |
43 | Bitmap gintama;
44 |
45 | public TouchImageView(Activity activity, Bitmap resBitmap) {
46 | super(activity);
47 | // gintama = BitmapFactory.decodeResource(getResources(), resId);
48 | gintama = resBitmap;
49 | DisplayMetrics dm = new DisplayMetrics();
50 | activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
51 | widthScreen = dm.widthPixels;
52 | heightScreen = dm.heightPixels;
53 |
54 | matrix = new Matrix();
55 | }
56 |
57 | protected void onDraw(Canvas canvas) {
58 | canvas.save();
59 | canvas.drawBitmap(gintama, matrix, null);
60 | canvas.restore();
61 | }
62 |
63 | public boolean onTouchEvent(MotionEvent event) {
64 | switch (event.getAction() & MotionEvent.ACTION_MASK) {
65 | case MotionEvent.ACTION_DOWN:
66 | mode = DRAG;
67 | x_down = event.getX();
68 | y_down = event.getY();
69 | savedMatrix.set(matrix);
70 | break;
71 | case MotionEvent.ACTION_POINTER_DOWN:
72 | mode = ZOOM;
73 | oldDist = spacing(event);
74 | oldRotation = rotation(event);
75 | savedMatrix.set(matrix);
76 | midPoint(mid, event);
77 | break;
78 | case MotionEvent.ACTION_MOVE:
79 | if (mode == ZOOM) {
80 | matrix1.set(savedMatrix);
81 | float rotation = rotation(event) - oldRotation;
82 | float newDist = spacing(event);
83 | float scale = newDist / oldDist;
84 | matrix1.postScale(scale, scale, mid.x, mid.y);// 縮放
85 | matrix1.postRotate(rotation, mid.x, mid.y);// 旋轉
86 | matrixCheck = matrixCheck();
87 | if (matrixCheck == false) {
88 | matrix.set(matrix1);
89 | invalidate();
90 | }
91 | } else if (mode == DRAG) {
92 | matrix1.set(savedMatrix);
93 | matrix1.postTranslate(event.getX() - x_down, event.getY()
94 | - y_down);// 平移
95 | matrixCheck = matrixCheck();
96 | matrixCheck = matrixCheck();
97 | if (matrixCheck == false) {
98 | matrix.set(matrix1);
99 | invalidate();
100 | }
101 | }
102 | break;
103 | case MotionEvent.ACTION_UP:
104 | case MotionEvent.ACTION_POINTER_UP:
105 | mode = NONE;
106 | break;
107 | }
108 | return true;
109 | }
110 |
111 | private boolean matrixCheck() {
112 | /*float[] f = new float[9];
113 | matrix1.getValues(f);
114 | // 图片4个顶点的坐标
115 | float x1 = f[0] * 0 + f[1] * 0 + f[2];
116 | float y1 = f[3] * 0 + f[4] * 0 + f[5];
117 | float x2 = f[0] * gintama.getWidth() + f[1] * 0 + f[2];
118 | float y2 = f[3] * gintama.getWidth() + f[4] * 0 + f[5];
119 | float x3 = f[0] * 0 + f[1] * gintama.getHeight() + f[2];
120 | float y3 = f[3] * 0 + f[4] * gintama.getHeight() + f[5];
121 | float x4 = f[0] * gintama.getWidth() + f[1] * gintama.getHeight() + f[2];
122 | float y4 = f[3] * gintama.getWidth() + f[4] * gintama.getHeight() + f[5];
123 | // 图片现宽度
124 | double width = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
125 | // 缩放比率判断
126 | if (width < widthScreen / 3 || width > widthScreen * 3) {
127 | return true;
128 | }
129 | // 出界判断
130 | if ((x1 < widthScreen / 3 && x2 < widthScreen / 3
131 | && x3 < widthScreen / 3 && x4 < widthScreen / 3)
132 | || (x1 > widthScreen * 2 / 3 && x2 > widthScreen * 2 / 3
133 | && x3 > widthScreen * 2 / 3 && x4 > widthScreen * 2 / 3)
134 | || (y1 < heightScreen / 3 && y2 < heightScreen / 3
135 | && y3 < heightScreen / 3 && y4 < heightScreen / 3)
136 | || (y1 > heightScreen * 2 / 3 && y2 > heightScreen * 2 / 3
137 | && y3 > heightScreen * 2 / 3 && y4 > heightScreen * 2 / 3)) {
138 | return true;
139 | } */
140 | return false;
141 | }
142 |
143 | // 触碰两点间距离
144 | private float spacing(MotionEvent event) {
145 | float x = event.getX(0) - event.getX(1);
146 | float y = event.getY(0) - event.getY(1);
147 | // return FloatMath.sqrt(x * x + y * y);
148 | return (float) Math.sqrt(x * x + y * y);
149 | }
150 |
151 | // 取手势中心点
152 | private void midPoint(PointF point, MotionEvent event) {
153 | float x = event.getX(0) + event.getX(1);
154 | float y = event.getY(0) + event.getY(1);
155 | point.set(x / 2, y / 2);
156 | }
157 |
158 | // 取旋转角度
159 | private float rotation(MotionEvent event) {
160 | double delta_x = (event.getX(0) - event.getX(1));
161 | double delta_y = (event.getY(0) - event.getY(1));
162 | double radians = Math.atan2(delta_y, delta_x);
163 | return (float) Math.toDegrees(radians);
164 | }
165 |
166 | // 将移动,缩放以及旋转后的图层保存为新图片
167 | // 本例中沒有用到該方法,需要保存圖片的可以參考
168 | public Bitmap CreatNewPhoto() {
169 | Bitmap bitmap = Bitmap.createBitmap(widthScreen, widthScreen,
170 | Config.ARGB_8888); // 背景图片
171 | Canvas canvas = new Canvas(bitmap); // 新建画布
172 | canvas.drawBitmap(gintama, matrix, null); // 画图片
173 | canvas.save(Canvas.ALL_SAVE_FLAG); // 保存画布
174 | canvas.restore();
175 | return bitmap;
176 | }
177 |
178 |
179 | }
180 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/picture/WaterMarkActivity.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.picture;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.graphics.Bitmap;
6 | import android.graphics.Bitmap.Config;
7 | import android.graphics.BitmapFactory;
8 | import android.graphics.Canvas;
9 | import android.graphics.Matrix;
10 | import android.net.Uri;
11 | import android.os.Bundle;
12 | import android.os.Handler;
13 | import android.view.View;
14 | import android.view.View.OnClickListener;
15 | import android.widget.Button;
16 | import android.widget.ImageView;
17 | import android.widget.RelativeLayout;
18 | import android.widget.RelativeLayout.LayoutParams;
19 |
20 | import com.example.jimageeditdemo.R;
21 | import com.pmmq.pmmqproject.config.Constant;
22 | import com.pmmq.pmmqproject.ui.tag.AddTagActivity;
23 | import com.pmmq.pmmqproject.util.Logger;
24 |
25 | import java.io.File;
26 | import java.io.FileOutputStream;
27 | import java.io.IOException;
28 | import java.io.OutputStream;
29 |
30 | /**
31 | * @author shark
32 | * @ClassName: WaterMarkActivity
33 | * @Description: 添加水印,有两种水印方式:1.与目标图片叠加(布局中已隐藏) 2.贴纸形式,可以移动、缩放、旋转
34 | * @date 2014年11月26日 上午10:52:45
35 | */
36 | public class WaterMarkActivity extends Activity implements OnClickListener {
37 |
38 | private String TAG = "WaterMarkActivity";
39 |
40 | public final static int REQ_CODE = 211;
41 |
42 | private RelativeLayout mRootLayout;
43 | private ImageView mImageView;
44 | private ImageView mWatermark1;
45 | private ImageView mWatermark2;
46 | private ImageView mWatermark3;
47 | private Button mNextBtn;
48 | private ImageView mWatermark4;
49 | private ImageView mWatermark5;
50 | private ImageView mWatermark6;
51 |
52 | private final Handler mHandler = new Handler();
53 |
54 | private Uri mImageUri; //目标图片的Uri
55 | private String mImagePath; //目标图片的路径
56 |
57 | private TouchImageView mWaterMarkView = null;
58 |
59 | private int[] mMarkRes = {
60 | R.drawable.wm_1,
61 | R.drawable.wm_2,
62 | R.drawable.wm_3
63 | };
64 |
65 | private int[] mMarkRes_2 = {
66 | R.drawable.wm_5,
67 | R.drawable.wm_6
68 | };
69 |
70 | @Override
71 | protected void onCreate(Bundle savedInstanceState) {
72 | // TODO Auto-generated method stub
73 | super.onCreate(savedInstanceState);
74 | setContentView(R.layout.activity_water_mark);
75 |
76 | //裁剪后传过来的图片路径
77 | mImagePath = getIntent().getStringExtra(TakePicActivity.CROP_IMAGE_URI);
78 | //裁剪后的uri
79 | mImageUri = Uri.parse(mImagePath);
80 | Logger.w(TAG, "imagePath:" + mImagePath);
81 | Logger.w(TAG, "mImageUri:" + mImageUri);
82 | initView();
83 |
84 | }
85 |
86 | private void initView() {
87 | mRootLayout = (RelativeLayout) findViewById(R.id.wm_image_layout);
88 | mImageView = (ImageView) findViewById(R.id.wm_image);
89 |
90 | int width = getWindowManager().getDefaultDisplay().getWidth();//获取屏幕高度
91 | //设置图片显示宽高为屏幕宽度
92 | LayoutParams params = new LayoutParams(width, width);
93 | mImageView.setLayoutParams(params);
94 | if (mImageUri != null) {
95 | mImageView.setImageURI(mImageUri);
96 | }
97 |
98 | mWatermark1 = (ImageView) findViewById(R.id.wm_mark1);
99 | mWatermark2 = (ImageView) findViewById(R.id.wm_mark2);
100 | mWatermark3 = (ImageView) findViewById(R.id.wm_mark3);
101 | mWatermark1.setOnClickListener(this);
102 | mWatermark2.setOnClickListener(this);
103 | mWatermark3.setOnClickListener(this);
104 |
105 | mWatermark4 = (ImageView) findViewById(R.id.wm_mark4);
106 | mWatermark5 = (ImageView) findViewById(R.id.wm_mark5);
107 | mWatermark6 = (ImageView) findViewById(R.id.wm_mark6);
108 | mWatermark4.setOnClickListener(this);
109 | mWatermark5.setOnClickListener(this);
110 | mWatermark6.setOnClickListener(this);
111 |
112 | mNextBtn = (Button) findViewById(R.id.wm_next_btn);
113 | mNextBtn.setOnClickListener(this);
114 |
115 | }
116 |
117 | @Override
118 | public void onClick(View v) {
119 | // TODO Auto-generated method stub
120 | switch (v.getId()) {
121 | case R.id.wm_mark1: //水印方式1,隐藏中
122 | addWaterMark(0);
123 | break;
124 | case R.id.wm_mark2:
125 | addWaterMark(1);
126 | break;
127 | case R.id.wm_mark3:
128 | addWaterMark(2);
129 | break;
130 | case R.id.wm_mark4:
131 | addWaterMark_2(10); //空 ,不添加水印
132 | break;
133 | case R.id.wm_mark5:
134 | addWaterMark_2(0); //水印方式2
135 | break;
136 | case R.id.wm_mark6:
137 | addWaterMark_2(1);
138 | break;
139 | case R.id.wm_next_btn:
140 | goToNextActivity();
141 | break;
142 | default:
143 | break;
144 | }
145 | }
146 |
147 | //添加水印贴纸,可以移动、缩放、旋转
148 | private void addWaterMark_2(int i) {
149 |
150 | if (i > mMarkRes_2.length) { //空 ,不添加水印
151 | if (mWaterMarkView != null) {
152 | mRootLayout.removeView(mWaterMarkView);
153 | mWaterMarkView = null;
154 | }
155 | } else {
156 | if (mWaterMarkView != null) {
157 | mRootLayout.removeView(mWaterMarkView);
158 | }
159 | //设置图片显示宽高为屏幕宽度
160 | LayoutParams params = new LayoutParams(Constant.displayWidth, Constant.displayWidth);
161 |
162 | Bitmap watermark = BitmapFactory.decodeResource(getResources(), mMarkRes_2[i]);
163 |
164 | int ww = watermark.getWidth();
165 | int wh = watermark.getHeight();
166 | Logger.w(TAG, "watermark ww:" + ww);
167 | Logger.w(TAG, "watermark wh:" + wh);
168 |
169 | //如果水印图片太大则压缩
170 | if (ww > Constant.displayWidth || wh > Constant.displayWidth) {
171 | // 缩放图片的尺寸
172 | float scaleWidth = (float) Constant.displayWidth / ww;
173 | float scaleHeight = (float) Constant.displayWidth / wh;
174 | float scale = Math.min(scaleWidth, scaleHeight) * (float) 0.8; //屏幕宽度的80%
175 | Matrix matrix = new Matrix();
176 | matrix.postScale(scale, scale);
177 | // 产生缩放后的Bitmap对象
178 | watermark = Bitmap.createBitmap(watermark, 0, 0, ww, wh, matrix, false);
179 | }
180 |
181 | TouchImageView touchImageView = new TouchImageView(this, watermark);
182 | mRootLayout.addView(touchImageView, params);
183 | mWaterMarkView = touchImageView;
184 | }
185 | }
186 |
187 | /**
188 | * 从TouchImageView中获取图片Bitmap
189 | *
190 | * @return Bitmap
191 | */
192 | private Bitmap getWaterMarkImage() {
193 | Bitmap photo = BitmapFactory.decodeFile(mImagePath);
194 | if (mWaterMarkView != null) {
195 | Bitmap mark = mWaterMarkView.CreatNewPhoto();
196 | Bitmap a = createBitmap(photo, mark);
197 |
198 | photo.recycle();
199 | mark.recycle();
200 | return a;
201 | } else {
202 | return photo;
203 | }
204 |
205 | }
206 |
207 | //添加水印,方式1,图片叠加
208 | private void addWaterMark(int i) {
209 | Bitmap photo = BitmapFactory.decodeFile(mImagePath);
210 | Bitmap mark = BitmapFactory.decodeResource(this.getResources(), mMarkRes[i]);
211 | Bitmap a = createBitmap(photo, mark);
212 | mImageView.setImageBitmap(a);
213 | photo.recycle();
214 | mark.recycle();
215 | // a.recycle();
216 | // saveMyBitmap(a);
217 | }
218 |
219 | /**
220 | * @param src
221 | * @param watermark
222 | * @return
223 | */
224 | private Bitmap createBitmap(Bitmap src, Bitmap watermark) {
225 | if (src == null) {
226 | return null;
227 | }
228 | int w = src.getWidth();
229 | int h = src.getHeight();
230 | Logger.d(TAG, "createBitmap w:" + w);
231 | Logger.d(TAG, "createBitmap h:" + h);
232 | int ww = watermark.getWidth();
233 | int wh = watermark.getHeight();
234 | Logger.d(TAG, "watermark ww:" + ww);
235 | Logger.d(TAG, "watermark wh:" + wh);
236 |
237 | // 缩放图片的尺寸
238 | float scaleWidth = (float) w / ww;
239 | float scaleHeight = (float) h / wh;
240 | Logger.d(TAG, "watermark scaleWidth:" + scaleWidth);
241 | Logger.d(TAG, "watermark scaleHeight:" + scaleHeight);
242 |
243 | Matrix matrix = new Matrix();
244 | matrix.postScale(scaleWidth, scaleHeight);
245 | // 产生缩放后的Bitmap对象
246 | Bitmap resizeBitmap = Bitmap.createBitmap(watermark, 0, 0, ww, wh, matrix, false);
247 | Logger.d(TAG, "resizeBitmap ww:" + resizeBitmap.getWidth());
248 | Logger.d(TAG, "resizeBitmap wh:" + resizeBitmap.getHeight());
249 |
250 |
251 | //create the new blank bitmap
252 | Bitmap newb = Bitmap.createBitmap(w, h, Config.ARGB_8888);
253 | //创建一个新的和SRC长度宽度一样的位图
254 | Canvas cv = new Canvas(newb);
255 | //draw src into
256 | cv.drawBitmap(src, 0, 0, null);//在 0,0坐标开始画入src
257 | //draw watermark into
258 | cv.drawBitmap(resizeBitmap, 0, 0, null);//在src的右下角画入水印
259 | //save all clip
260 | cv.save(Canvas.ALL_SAVE_FLAG);//保存
261 | //store
262 | cv.restore();//存储
263 |
264 | resizeBitmap.recycle();
265 | return newb;
266 | }
267 |
268 | /**
269 | * 将Bitmap放入缓存,
270 | *
271 | * @param bitmap
272 | * @param filePath
273 | * @return void
274 | * @Title: saveDrawableToCache
275 | * @date 2012-12-14 上午9:27:38
276 | */
277 | private void saveDrawableToCache(Bitmap bitmap, String filePath) {
278 |
279 | try {
280 | File file = new File(filePath);
281 |
282 | file.createNewFile();
283 |
284 | OutputStream outStream = new FileOutputStream(file);
285 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
286 | outStream.flush();
287 | outStream.close();
288 |
289 | } catch (IOException e) {
290 |
291 | e.printStackTrace();
292 | }
293 | }
294 |
295 | /**
296 | * 下一步
297 | */
298 | private void goToNextActivity() {
299 | //保存图片
300 | // final Bitmap photo = ((BitmapDrawable)mImageView.getDrawable()).getBitmap();
301 |
302 | final Bitmap photo = getWaterMarkImage();
303 |
304 | final String wmImagePath = mImagePath + "_water_mark";
305 | Logger.w(TAG, "goToNextActivity wmImagePath:" + wmImagePath);
306 | mHandler.post(new Runnable() {
307 |
308 | @Override
309 | public void run() {
310 | // TODO Auto-generated method stub
311 |
312 | saveDrawableToCache(photo, wmImagePath);
313 | // photo.recycle();
314 | }
315 |
316 | });
317 |
318 | Intent intent = new Intent(this, AddTagActivity.class);
319 | intent.putExtra(TakePicActivity.CROP_IMAGE_URI, wmImagePath);
320 | startActivityForResult(intent, REQ_CODE);
321 | }
322 |
323 | @Override
324 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
325 | // TODO Auto-generated method stub
326 | super.onActivityResult(requestCode, resultCode, data);
327 | Logger.d(TAG, "onActivityResult ");
328 |
329 | if (resultCode == RESULT_OK) {
330 | if (requestCode == REQ_CODE) {
331 | String imagePath = data.getStringExtra("tag_image_path");
332 | Intent intent = new Intent();
333 | intent.putExtra("tag_image_path", imagePath);
334 | setResult(RESULT_OK, intent);
335 | finish();
336 | }
337 | }
338 | }
339 | }
340 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/picture/WaterMarkActivity_ImageFilter.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.picture;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Activity;
5 | import android.content.Intent;
6 | import android.graphics.Bitmap;
7 | import android.graphics.BitmapFactory;
8 | import android.graphics.drawable.BitmapDrawable;
9 | import android.graphics.drawable.Drawable;
10 | import android.net.Uri;
11 | import android.os.Build;
12 | import android.os.Bundle;
13 | import android.os.Handler;
14 | import android.view.View;
15 | import android.view.View.OnClickListener;
16 | import android.widget.Button;
17 | import android.widget.ImageView;
18 | import android.widget.LinearLayout;
19 |
20 | import com.example.jimageeditdemo.R;
21 | import com.example.jimageeditdemo.api.BitmapFilter;
22 | import com.pmmq.pmmqproject.ui.tag.AddTagActivity;
23 | import com.pmmq.pmmqproject.util.Logger;
24 |
25 | import java.io.File;
26 | import java.io.FileOutputStream;
27 | import java.io.IOException;
28 | import java.io.OutputStream;
29 |
30 | /**
31 | * @author shark
32 | * @ClassName: WaterMarkActivity
33 | * @Description: 添加水印,有两种水印方式:1.与目标图片叠加(布局中已隐藏) 2.贴纸形式,可以移动、缩放、旋转
34 | * @date 2014年11月26日 上午10:52:45
35 | */
36 | public class WaterMarkActivity_ImageFilter extends Activity implements OnClickListener {
37 | private Bitmap originalBitmap;
38 | private Bitmap sBitmap;
39 | private Button original_btn, button_change_to_gray, button_change_to_old,
40 | button_change_to_ice, button_change_to_carton, button_change_to_soft,
41 | button_change_to_eclosion, button_change_to_light, button_change_to_haha;
42 |
43 | private ImageView mImageView;//显示图片的
44 | private Button mNextBtn;//下一步
45 |
46 | private String TAG = "WaterMarkActivity";
47 |
48 | public final static int REQ_CODE = 211;
49 |
50 | private final Handler mHandler = new Handler();
51 |
52 | private Uri mImageUri; //目标图片的Uri
53 | private String mImagePath; //目标图片的路径
54 |
55 | private TouchImageView mWaterMarkView = null;
56 |
57 |
58 | @Override
59 | protected void onCreate(Bundle savedInstanceState) {
60 | // TODO Auto-generated method stub
61 | super.onCreate(savedInstanceState);
62 | setContentView(R.layout.activity_water_mark_image_filter);
63 |
64 | //裁剪后传过来的图片路径
65 | mImagePath = getIntent().getStringExtra(TakePicActivity.CROP_IMAGE_URI);
66 | //裁剪后的uri
67 | mImageUri = Uri.parse(mImagePath);
68 | originalBitmap = BitmapFactory.decodeFile(mImagePath);
69 | initView();
70 |
71 | }
72 |
73 | private void initView() {
74 | findViewById(R.id.original_btn).setOnClickListener(this);//原始照片
75 |
76 | original_btn = (Button) findViewById(R.id.original_btn);
77 | button_change_to_gray = (Button) findViewById(R.id.button_change_to_gray);
78 | button_change_to_old = (Button) findViewById(R.id.button_change_to_old);
79 | button_change_to_ice = (Button) findViewById(R.id.button_change_to_ice);
80 | button_change_to_carton = (Button) findViewById(R.id.button_change_to_carton);
81 | button_change_to_soft = (Button) findViewById(R.id.button_change_to_soft);
82 | button_change_to_eclosion = (Button) findViewById(R.id.button_change_to_eclosion);
83 | button_change_to_light = (Button) findViewById(R.id.button_change_to_light);
84 | button_change_to_haha = (Button) findViewById(R.id.button_change_to_haha);
85 |
86 | original_btn.setOnClickListener(this);
87 | button_change_to_gray.setOnClickListener(this);
88 | button_change_to_old.setOnClickListener(this);
89 | button_change_to_ice.setOnClickListener(this);
90 | button_change_to_carton.setOnClickListener(this);
91 | button_change_to_soft.setOnClickListener(this);
92 | button_change_to_eclosion.setOnClickListener(this);
93 | button_change_to_light.setOnClickListener(this);
94 | button_change_to_haha.setOnClickListener(this);
95 |
96 | // originalBitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.huishu);
97 |
98 | mImageView = (ImageView) findViewById(R.id.wm_image);
99 |
100 | int width = getWindowManager().getDefaultDisplay().getWidth();//获取屏幕高度
101 | //设置图片显示宽高为屏幕宽度
102 | LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, width);
103 | mImageView.setLayoutParams(params);
104 | mImageView.setImageBitmap(originalBitmap);
105 | // if (mImageUri != null) {
106 | // mImageView.setImageURI(mImageUri);
107 | // }
108 | mNextBtn = (Button) findViewById(R.id.wm_next_btn);
109 | mNextBtn.setOnClickListener(this);
110 |
111 | initFilter();
112 | }
113 |
114 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
115 | private void initFilter() {
116 | //无滤镜效果
117 | Drawable bd = new BitmapDrawable(getResources(), originalBitmap);
118 | original_btn.setBackground(bd);
119 |
120 | //黑白效果
121 | sBitmap = BitmapFilter.changeStyle(originalBitmap, BitmapFilter.GRAY_STYLE);
122 | bd = new BitmapDrawable(getResources(), sBitmap);
123 | button_change_to_gray.setBackground(bd);
124 |
125 |
126 | //怀旧效果
127 | sBitmap = BitmapFilter.changeStyle(originalBitmap, BitmapFilter.OLD_STYLE);
128 | bd = new BitmapDrawable(getResources(), sBitmap);
129 | button_change_to_old.setBackground(bd);
130 |
131 | //冰冻效果
132 | sBitmap = BitmapFilter.changeStyle(originalBitmap, BitmapFilter.ICE_STYLE);
133 | bd = new BitmapDrawable(getResources(), sBitmap);
134 | button_change_to_ice.setBackground(bd);
135 |
136 | //连环画效果
137 | sBitmap = BitmapFilter.changeStyle(originalBitmap, BitmapFilter.CARTON_STYLE);
138 | bd = new BitmapDrawable(getResources(), sBitmap);
139 | button_change_to_carton.setBackground(bd);
140 |
141 | //柔滑美白
142 | sBitmap = BitmapFilter.changeStyle(originalBitmap, BitmapFilter.SOFTNESS_STYLE);
143 | bd = new BitmapDrawable(getResources(), sBitmap);
144 | button_change_to_soft.setBackground(bd);
145 |
146 | //羽化效果
147 | sBitmap = BitmapFilter.changeStyle(originalBitmap, BitmapFilter.ECLOSION_STYLE);
148 | bd = new BitmapDrawable(getResources(), sBitmap);
149 | button_change_to_eclosion.setBackground(bd);
150 |
151 | //光照效果
152 | sBitmap = BitmapFilter.changeStyle(originalBitmap, BitmapFilter.LIGHT_STYLE);
153 | bd = new BitmapDrawable(getResources(), sBitmap);
154 | button_change_to_light.setBackground(bd);
155 | //哈哈镜效果
156 | sBitmap = BitmapFilter.changeStyle(originalBitmap, BitmapFilter.HAHA_STYLE);
157 | bd = new BitmapDrawable(getResources(), sBitmap);
158 | button_change_to_haha.setBackground(bd);
159 |
160 | }
161 |
162 | @Override
163 | public void onDestroy() {
164 | super.onDestroy();
165 | if (sBitmap != null) {
166 | sBitmap.recycle();
167 | sBitmap = null;
168 | }
169 | }
170 |
171 | int styleNo = BitmapFilter.GRAY_STYLE;
172 |
173 | @Override
174 | public void onClick(View v) {
175 | // TODO Auto-generated method stub
176 | // if (sBitmap != null) {
177 | // sBitmap.recycle();
178 | // sBitmap = null;
179 | // }
180 |
181 | switch (v.getId()) {
182 | case R.id.wm_next_btn:
183 | goToNextActivity();
184 | break;
185 | case R.id.original_btn:
186 | mImageView.setImageBitmap(originalBitmap);
187 | return;
188 | case R.id.button_change_to_gray:
189 | styleNo = BitmapFilter.GRAY_STYLE;
190 | break;
191 |
192 | case R.id.button_change_to_old:
193 | styleNo = BitmapFilter.OLD_STYLE;
194 | break;
195 | case R.id.button_change_to_ice:
196 | styleNo = BitmapFilter.ICE_STYLE;
197 | break;
198 | case R.id.button_change_to_carton:
199 | //连环画效果
200 | styleNo = BitmapFilter.CARTON_STYLE;
201 | break;
202 |
203 | case R.id.button_change_to_soft:
204 | //羽化效果
205 | styleNo = BitmapFilter.SOFTNESS_STYLE;
206 | break;
207 | case R.id.button_change_to_eclosion:
208 | styleNo = BitmapFilter.ECLOSION_STYLE;
209 | break;
210 | case R.id.button_change_to_light:
211 | styleNo = BitmapFilter.LIGHT_STYLE;
212 | break;
213 | case R.id.button_change_to_haha:
214 | //哈哈镜效果
215 | styleNo = BitmapFilter.HAHA_STYLE;
216 | break;
217 | //下面几个效果暂时不用
218 | // case R.id.button_change_to_block:
219 | // //版画效果
220 | // styleNo = BitmapFilter.BLOCK_STYLE;
221 | // break;
222 | // case R.id.button_change_to_oid:
223 | // //油画效果
224 | // styleNo = BitmapFilter.OIL_STYLE;
225 | // break;
226 | // case R.id.button_change_to_molten:
227 | // //铸融效果
228 | // styleNo = BitmapFilter.MOLTEN_STYLE;
229 | // break;
230 | // case R.id.button_change_to_invert:
231 | // //反色效果
232 | // styleNo = BitmapFilter.INVERT_STYLE;
233 | // break;
234 | // case R.id.button_change_to_relief:
235 | // //浮雕
236 | // styleNo = BitmapFilter.RELIEF_STYLE;
237 | // break;
238 |
239 | }
240 | sBitmap = BitmapFilter.changeStyle(originalBitmap, styleNo);
241 | mImageView.setImageBitmap(sBitmap);
242 | }
243 |
244 |
245 | /**
246 | * 将Bitmap放入缓存,
247 | *
248 | * @param bitmap
249 | * @param filePath
250 | * @return void
251 | * @Title: saveDrawableToCache
252 | * @date 2012-12-14 上午9:27:38
253 | */
254 | private void saveDrawableToCache(Bitmap bitmap, String filePath) {
255 | try {
256 | File file = new File(filePath);
257 | file.createNewFile();
258 | OutputStream outStream = new FileOutputStream(file);
259 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
260 | outStream.flush();
261 | outStream.close();
262 |
263 | } catch (IOException e) {
264 | e.printStackTrace();
265 | }
266 | }
267 |
268 | /**
269 | * 下一步
270 | */
271 | private void goToNextActivity() {
272 | //保存图片
273 | // final Bitmap photo = ((BitmapDrawable)mImageView.getDrawable()).getBitmap();
274 |
275 | // final Bitmap photo = getWaterMarkImage();
276 |
277 | final String wmImagePath = mImagePath + "_water_mark";
278 | Logger.w(TAG, "goToNextActivity wmImagePath:" + wmImagePath);
279 | mHandler.post(new Runnable() {
280 |
281 | @Override
282 | public void run() {
283 | // TODO Auto-generated method stub
284 |
285 | // saveDrawableToCache(photo, wmImagePath);
286 | saveDrawableToCache(sBitmap, wmImagePath);
287 | // photo.recycle();
288 | }
289 |
290 | });
291 |
292 | Intent intent = new Intent(this, AddTagActivity.class);
293 | intent.putExtra(TakePicActivity.CROP_IMAGE_URI, wmImagePath);
294 | startActivityForResult(intent, REQ_CODE);
295 | }
296 |
297 | @Override
298 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
299 | // TODO Auto-generated method stub
300 | super.onActivityResult(requestCode, resultCode, data);
301 | Logger.d(TAG, "onActivityResult ");
302 |
303 | if (resultCode == RESULT_OK) {
304 | if (requestCode == REQ_CODE) {
305 | String imagePath = data.getStringExtra("tag_image_path");
306 | originalBitmap = BitmapFactory.decodeFile(imagePath);
307 | initView();
308 | Intent intent = new Intent();
309 | intent.putExtra("tag_image_path", imagePath);
310 | setResult(RESULT_OK, intent);
311 | finish();
312 | }
313 | }
314 | }
315 |
316 |
317 | }
318 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/tag/EmojiconTextView.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.tag;
2 |
3 | import android.content.Context;
4 | import android.text.SpannableStringBuilder;
5 | import android.util.AttributeSet;
6 | import android.widget.TextView;
7 |
8 | public class EmojiconTextView extends TextView {
9 | private int TextSize;
10 |
11 | public EmojiconTextView(Context paramContext) {
12 | super(paramContext);
13 | a(null);
14 | }
15 |
16 | public EmojiconTextView(Context paramContext, AttributeSet paramAttributeSet) {
17 | super(paramContext, paramAttributeSet);
18 | a(paramAttributeSet);
19 | }
20 |
21 | public EmojiconTextView(Context paramContext,
22 | AttributeSet paramAttributeSet, int paramInt) {
23 | super(paramContext, paramAttributeSet, paramInt);
24 | a(paramAttributeSet);
25 | }
26 |
27 | private void a(AttributeSet paramAttributeSet) {
28 | if (paramAttributeSet == null){
29 | this.TextSize = (int) getTextSize();
30 | }else{
31 | // TypedArray localTypedArray = getContext().obtainStyledAttributes(paramAttributeSet, Emojicon);
32 | // this.TextSize = (int) localTypedArray.getDimension(0, getTextSize());
33 | // localTypedArray.recycle();
34 | }
35 | setText(getText());
36 | }
37 |
38 | public void setEmojiconSize(int paramInt) {
39 | this.TextSize = paramInt;
40 | }
41 |
42 | public void setText(CharSequence mCharSequence, TextView.BufferType mBufferType) {
43 | SpannableStringBuilder localSpannableStringBuilder = new SpannableStringBuilder(mCharSequence);
44 | // uv.a(getContext(), localSpannableStringBuilder, this.TextSize);
45 | super.setText(localSpannableStringBuilder, mBufferType);
46 | }
47 |
48 | // public static final int[] Emojicon = { 2130772074 };
49 | // public static final int Emojicon_emojiconSize;
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/tag/PreViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.tag;
2 |
3 | import com.example.jimageeditdemo.R;
4 | import com.pmmq.pmmqproject.ui.picture.TakePicActivity;
5 | import com.pmmq.pmmqproject.util.Logger;
6 |
7 | import android.app.Activity;
8 | import android.net.Uri;
9 | import android.os.Bundle;
10 | import android.widget.ImageView;
11 |
12 | public class PreViewActivity extends Activity{
13 |
14 | private String TAG = "PreViewActivity";
15 |
16 | private Uri mImageUri; //目标图片的Uri
17 | private String mImagePath; //目标图片的路径
18 |
19 | private ImageView mImageView;
20 |
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | // TODO Auto-generated method stub
24 | super.onCreate(savedInstanceState);
25 | setContentView(R.layout.activity_pre_view);
26 |
27 | mImagePath = getIntent().getStringExtra("tag_image_path");
28 | mImageUri = Uri.parse(mImagePath);
29 | Logger.d(TAG, "imagePath:" + mImagePath);
30 | Logger.d(TAG, "mImageUri:" + mImageUri);
31 |
32 | initView();
33 |
34 | }
35 |
36 | private void initView(){
37 | mImageView = (ImageView)findViewById(R.id.pv_image);
38 | if(mImageUri != null){
39 | mImageView.setImageURI(mImageUri);
40 | }
41 |
42 | }
43 |
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/tag/ShowTagActivity.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.tag;
2 |
3 | import android.app.Activity;
4 | import android.net.Uri;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.view.View.OnClickListener;
8 | import android.widget.ImageView;
9 | import android.widget.RelativeLayout;
10 | import android.widget.RelativeLayout.LayoutParams;
11 | import android.widget.Toast;
12 |
13 | import com.example.jimageeditdemo.R;
14 | import com.pmmq.pmmqproject.config.Constant;
15 | import com.pmmq.pmmqproject.ui.picture.TakePicActivity;
16 | import com.pmmq.pmmqproject.ui.tag.TagView.TagViewListener;
17 | import com.pmmq.pmmqproject.util.Logger;
18 |
19 | import org.json.JSONArray;
20 | import org.json.JSONException;
21 | import org.json.JSONObject;
22 |
23 | import java.util.ArrayList;
24 | import java.util.List;
25 |
26 | public class ShowTagActivity extends Activity implements OnClickListener, TagViewListener {
27 | private String TAG = "ShowTagActivity";
28 |
29 | private static int IMAGEDISPLAYWIDTH = 300; //此处是image的显示宽高,标签的坐标是在图片中的比例
30 |
31 | private Uri mImageUri; //目标图片的Uri
32 | private String mImagePath; //目标图片的路径
33 |
34 | private ImageView mImageView;
35 | private RelativeLayout mImageRootLayout;
36 |
37 | private List tagViews = new ArrayList();
38 | private List tagInfoList = new ArrayList();
39 |
40 | @Override
41 | protected void onCreate(Bundle savedInstanceState) {
42 | // TODO Auto-generated method stub
43 | super.onCreate(savedInstanceState);
44 | setContentView(R.layout.activity_show_tag);
45 |
46 | mImagePath = getIntent().getStringExtra(TakePicActivity.CROP_IMAGE_URI);
47 | mImageUri = Uri.parse(mImagePath);
48 | Logger.d(TAG, "imagePath:" + mImagePath);
49 | Logger.d(TAG, "mImageUri:" + mImageUri);
50 |
51 | String tagInfoListStr = getIntent().getStringExtra("tagInfoList");
52 | Logger.w(TAG, "tagInfoListStr.toString():" + tagInfoListStr.toString());
53 | parseInfoData(tagInfoListStr);
54 |
55 | initView();
56 |
57 | addTagView();
58 | }
59 |
60 | private void initView() {
61 | mImageView = (ImageView) findViewById(R.id.st_image);
62 | mImageView.setOnClickListener(this);
63 | mImageRootLayout = (RelativeLayout) findViewById(R.id.st_image_layout);
64 |
65 | if (mImageUri != null) {
66 | mImageView.setImageURI(mImageUri);
67 | }
68 |
69 | }
70 |
71 | private void addTagView() {
72 |
73 | for (TagInfo tagInfo : tagInfoList) {
74 | TagView tagView = null;
75 |
76 | //标签的坐标pic_x、pic_y是在图片中的比例,所以要根据显示的图片大小计算出准确位置
77 | double pointX = tagInfo.pic_x * IMAGEDISPLAYWIDTH * Constant.scale;
78 | double pointY = tagInfo.pic_y * IMAGEDISPLAYWIDTH * Constant.scale;
79 |
80 | switch (tagInfo.direct) {
81 | case Left:
82 | tagView = new TagViewLeft(this, null);
83 |
84 | tagInfo.leftMargin = (int) (pointX - 15 * Constant.scale); //根据屏幕密度计算使动画中心在点击点,15dp是margin
85 | tagInfo.topMargin = (int) (pointY - 15 * Constant.scale);
86 | tagInfo.rightMargin = 0;
87 | tagInfo.bottomMargin = 0;
88 | break;
89 | case Right:
90 | tagView = new TagViewRight(this, null);
91 |
92 | tagInfo.leftMargin = 0;
93 | tagInfo.topMargin = (int) (pointY - 15 * Constant.scale);
94 | tagInfo.rightMargin = (int) (IMAGEDISPLAYWIDTH * Constant.scale) - (int) pointX - (int) (15 * Constant.scale);
95 | tagInfo.bottomMargin = 0;
96 | break;
97 | }
98 |
99 | tagView.setData(tagInfo);
100 | tagView.setTagViewListener(this);
101 | RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
102 | LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
103 | params.setMargins(tagInfo.leftMargin, tagInfo.topMargin, tagInfo.rightMargin, tagInfo.bottomMargin);
104 | mImageRootLayout.addView(tagView, params);
105 | tagViews.add(tagView);
106 | }
107 | }
108 |
109 | @Override
110 | public void onClick(View v) {
111 | // TODO Auto-generated method stub
112 | switch (v.getId()) {
113 | case R.id.st_image:
114 | showOrHideTagView();
115 | break;
116 |
117 | default:
118 | break;
119 | }
120 | }
121 |
122 | /**
123 | * 显示隐藏标签
124 | */
125 | private void showOrHideTagView() {
126 | for (TagView tagView : tagViews) {
127 | if (tagView.isShow) {
128 | tagView.setVisibility(View.GONE);
129 | } else {
130 | tagView.setVisibility(View.VISIBLE);
131 | }
132 | }
133 | }
134 |
135 | private void parseInfoData(String infoStr) {
136 |
137 | try {
138 | JSONArray jsonArray = new JSONArray(infoStr);
139 |
140 | for (int i = 0; i < jsonArray.length(); i++) {
141 | JSONObject infoObject = jsonArray.getJSONObject(i);
142 | TagInfo tagInfo = new TagInfo().getInstance(infoObject);
143 | tagInfoList.add(tagInfo);
144 | }
145 | Logger.w(TAG, "tagInfoList.toString():" + tagInfoList.toString());
146 |
147 | } catch (JSONException e) {
148 | // TODO Auto-generated catch block
149 | e.printStackTrace();
150 | }
151 | }
152 |
153 | @Override
154 | public void onTagViewClicked(View view, TagInfo info) {
155 | // TODO Auto-generated method stub
156 | Toast.makeText(this, info.bname, Toast.LENGTH_SHORT).show();
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/tag/TagInfo.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.tag;
2 |
3 | import java.io.Serializable;
4 |
5 | import org.json.JSONObject;
6 |
7 | import android.os.Parcel;
8 | import android.os.Parcelable;
9 |
10 | public final class TagInfo implements Parcelable, Serializable {
11 | private static final long serialVersionUID = -2939266917839493174L;
12 | public String bname = "";
13 | public long bid = 0L;
14 | public double pic_x = 0.0D; //点击点在图片中的位置,百分比
15 | public double pic_y = 0.0D; //点击点在图片中的位置,百分比
16 | public Direction direct = Direction.Left;
17 | public Type type = Type.Undefined;
18 |
19 | public int leftMargin;
20 | public int topMargin;
21 | public int rightMargin;
22 | public int bottomMargin;
23 |
24 | public enum Direction {
25 | Left("left"), Right("right");
26 |
27 | private Direction(String valString) {
28 | this.valueString = valString;
29 | }
30 |
31 | public static int size(){
32 | return Direction.values().length;
33 | }
34 |
35 | public String valueString;
36 |
37 | public String toString(){
38 | return valueString;
39 | }
40 |
41 | public static Direction valueof(String vaString){
42 | if(vaString.equals("left")){
43 | return Direction.Left;
44 | }else if(vaString.equals("right")){
45 | return Direction.Right;
46 | }else{
47 | return null;
48 | }
49 | }
50 | }
51 |
52 | public enum Type {
53 | Undefined("undefined"),Exists("exists"),CustomPoint("custom_point"),OfficalPoint("offical_point");
54 |
55 | private Type(String typeString) {
56 | this.valueString = typeString;
57 | }
58 |
59 | public static int size(){
60 | return Type.values().length;
61 | }
62 |
63 | public String valueString;
64 |
65 | public String toString(){
66 | return valueString;
67 | }
68 |
69 | public static Type valueof(String vaString){
70 | if(vaString.equals("undefined")){
71 | return Type.Undefined;
72 | }else if(vaString.equals("exists")){
73 | return Type.Exists;
74 | }else if(vaString.equals("custom_point")){
75 | return Type.CustomPoint;
76 | }else if(vaString.equals("offical_point")){
77 | return Type.OfficalPoint;
78 | }else{
79 | return null;
80 | }
81 | }
82 | }
83 |
84 | public TagInfo() {
85 | }
86 |
87 | private TagInfo(Parcel paramParcel) {
88 | this.bname = paramParcel.readString();
89 | this.bid = paramParcel.readLong();
90 | this.pic_x = paramParcel.readDouble();
91 | this.pic_y = paramParcel.readDouble();
92 | this.direct = Direction.valueof(paramParcel.readString());
93 | this.type = Type.valueof(paramParcel.readString());
94 | }
95 |
96 | public TagInfo(JSONObject paramJSONObject) {
97 | String str = null;
98 | try {
99 | this.bid = paramJSONObject.getLong("bid");
100 | this.bname = paramJSONObject.getString("bname");
101 | this.pic_x = paramJSONObject.getDouble("pic_x");
102 | this.pic_y = paramJSONObject.getDouble("pic_y");
103 | this.direct = Direction.valueof(paramJSONObject.getString("direct"));
104 | if(null == direct){
105 | throw new RuntimeException("taginfo no direction");
106 | }
107 | this.type = Type.Undefined;
108 | if (!paramJSONObject.has("type")) {
109 | return;
110 | }
111 | str = paramJSONObject.getString("type");
112 | if (str.equals("exists")) {
113 | this.type = Type.Exists;
114 | return;
115 | }
116 | if (str.equals("custom_point")) {
117 | this.type = Type.CustomPoint;
118 | return;
119 | }
120 | if (str.equals("offical_point")) {
121 | this.type = Type.OfficalPoint;
122 | }
123 | } catch (Exception e) {
124 | e.printStackTrace();
125 | }
126 | }
127 |
128 | public TagInfo getInstance(JSONObject paramJSONObject) {
129 | return new TagInfo(paramJSONObject);
130 | }
131 |
132 | public final JSONObject getjson() {
133 | JSONObject jsonobject = new JSONObject();
134 | try {
135 | jsonobject.put("bid", bid);
136 | jsonobject.put("bname", bname);
137 | jsonobject.put("pic_x", String.valueOf(pic_x));
138 | jsonobject.put("pic_y", String.valueOf(pic_y));
139 | jsonobject.put("direct", direct.toString());
140 | jsonobject.put("type", type.toString());
141 | return jsonobject;
142 | } catch (Exception localException) {
143 | localException.printStackTrace();
144 | }
145 | return jsonobject;
146 | }
147 |
148 | public final int describeContents() {
149 | return 0;
150 | }
151 |
152 | public final void writeToParcel(Parcel parcel, int i) {
153 | parcel.writeString(bname);
154 | parcel.writeLong(bid);
155 | parcel.writeDouble(pic_x);
156 | parcel.writeDouble(pic_y);
157 | parcel.writeString(direct.toString());
158 | parcel.writeString(type.toString());
159 | }
160 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/tag/TagView.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.tag;
2 |
3 | import com.example.jimageeditdemo.R;
4 |
5 | import android.content.Context;
6 | import android.os.Handler;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 | import android.view.animation.Animation;
10 | import android.view.animation.Animation.AnimationListener;
11 | import android.view.animation.AnimationUtils;
12 | import android.widget.ImageView;
13 | import android.widget.RelativeLayout;
14 | import android.widget.TextView;
15 |
16 | public class TagView extends RelativeLayout implements View.OnClickListener {
17 | public Animation blackAnimation1;
18 | public Animation blackAnimation2;
19 | public Animation whiteAnimation;
20 |
21 | protected TextView textview;//文字描述显示View
22 | public ImageView blackIcon1;//黑色圆圈View
23 | public ImageView blackIcon2;//黑色圆圈View
24 | protected ImageView brandIcon;//白色圆圈View
25 | protected ImageView geoIcon;//白色定位圆圈View
26 | public ImageView viewPointer;//指向brandIcon或者geoIcon,根据设置的类型的不同
27 |
28 | public boolean isShow = false;
29 | private TagViewListener listener;
30 | private Handler handler = new Handler();
31 |
32 | public interface TagViewListener {
33 | public void onTagViewClicked(View view, TagInfo info);
34 | }
35 |
36 | public TagView(Context context) {
37 | this(context, null);
38 | }
39 |
40 | public TagView(Context context, AttributeSet attrs) {
41 | super(context, attrs);
42 | this.blackAnimation1 = AnimationUtils.loadAnimation(context, R.anim.black_anim);
43 | this.blackAnimation2 = AnimationUtils.loadAnimation(context, R.anim.black_anim);
44 | this.whiteAnimation = AnimationUtils.loadAnimation(context, R.anim.white_anim);
45 | this.setOnClickListener(this);
46 | }
47 |
48 | public final void clearAnim() {
49 | this.blackIcon1.clearAnimation();
50 | this.blackIcon2.clearAnimation();
51 | this.viewPointer.clearAnimation();
52 | this.isShow = false;
53 | }
54 |
55 | public final void startBlackAnimation1(final ImageView imageView) {
56 | blackAnimation1.setAnimationListener(new AnimationListener() {
57 | @Override
58 | public void onAnimationStart(Animation animation) {
59 | }
60 | @Override
61 | public void onAnimationRepeat(Animation animation) {
62 | }
63 | @Override
64 | public void onAnimationEnd(Animation animation) {
65 | if (!isShow) {
66 | return;
67 | }
68 | handler.postDelayed(new Runnable() {
69 | @Override
70 | public void run() {
71 | imageView.clearAnimation();
72 | blackAnimation1.reset();
73 | startBlackAnimation2(blackIcon2);
74 | }
75 | }, 10);
76 | }
77 | });
78 | imageView.clearAnimation();
79 | imageView.startAnimation(blackAnimation1);
80 | }
81 |
82 | public final void startBlackAnimation2(final ImageView imageView) {
83 | blackAnimation2.setAnimationListener(new AnimationListener() {
84 | @Override
85 | public void onAnimationStart(Animation animation) {
86 | }
87 | @Override
88 | public void onAnimationRepeat(Animation animation) {
89 | }
90 | @Override
91 | public void onAnimationEnd(Animation animation) {
92 | if (!isShow) {
93 | return;
94 | }
95 | handler.postDelayed(new Runnable() {
96 |
97 | @Override
98 | public void run() {
99 | imageView.clearAnimation();
100 | blackAnimation2.reset();
101 | startWhiteAnimation(viewPointer);
102 | }
103 | }, 10);
104 | }
105 | });
106 | imageView.clearAnimation();
107 | imageView.startAnimation(blackAnimation2);
108 | }
109 |
110 | public final void startWhiteAnimation(final ImageView imageView) {
111 | whiteAnimation.setAnimationListener(new AnimationListener() {
112 | @Override
113 | public void onAnimationStart(Animation animation) {
114 | }
115 | @Override
116 | public void onAnimationRepeat(Animation animation) {
117 | }
118 | @Override
119 | public void onAnimationEnd(Animation animation) {
120 | if (!isShow) {
121 | return;
122 | }
123 | handler.postDelayed(new Runnable() {
124 | @Override
125 | public void run() {
126 | imageView.clearAnimation();
127 | whiteAnimation.reset();
128 | startBlackAnimation1(blackIcon1);
129 | }
130 | }, 10);
131 | }
132 | });
133 | imageView.clearAnimation();
134 | imageView.startAnimation(whiteAnimation);
135 | }
136 |
137 | protected final void setVisible() {
138 | if ((textview != null) && (taginfo != null)) {
139 | if (TagInfo.Type.CustomPoint != taginfo.type && TagInfo.Type.OfficalPoint != taginfo.type) {
140 | this.viewPointer = this.brandIcon;
141 | this.geoIcon.setVisibility(View.VISIBLE);
142 | this.brandIcon.setVisibility(View.GONE);
143 | } else {
144 | this.viewPointer = this.geoIcon;
145 | this.geoIcon.setVisibility(View.GONE);
146 | this.brandIcon.setVisibility(View.VISIBLE);
147 | }
148 | textview.setText(taginfo.bname);
149 | textview.setVisibility(View.VISIBLE);
150 | }
151 | clearAnim();
152 | show();
153 | }
154 |
155 | public void show() {
156 | if (this.isShow) {
157 | return;
158 | }
159 | this.isShow = true;
160 | startWhiteAnimation(viewPointer);
161 | }
162 |
163 | private TagInfo taginfo;
164 |
165 | public void setData(TagInfo mTagInfo) {
166 | this.taginfo = mTagInfo;
167 | setVisible();
168 | }
169 |
170 | public TagInfo getData() {
171 | return taginfo;
172 | }
173 |
174 | public void setTagViewListener(TagViewListener listener) {
175 | this.listener = listener;
176 | }
177 |
178 | @Override
179 | public void onClick(View view) {
180 | if (null != listener) {
181 | listener.onTagViewClicked(view, taginfo);
182 | }
183 | }
184 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/tag/TagViewLeft.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.tag;
2 |
3 | import com.example.jimageeditdemo.R;
4 |
5 | import android.content.Context;
6 | import android.util.AttributeSet;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | public class TagViewLeft extends TagView {
13 | public TagViewLeft(Context paramContext) {
14 | this(paramContext, null);
15 | }
16 |
17 | public TagViewLeft(Context paramContext, AttributeSet paramAttributeSet) {
18 | super(paramContext, paramAttributeSet);
19 | LayoutInflater.from(paramContext).inflate(R.layout.tag_view_left, this);
20 | this.textview = ((TextView) findViewById(R.id.text));
21 | this.textview.getBackground().setAlpha(178);
22 | this.textview.setVisibility(View.VISIBLE);
23 | this.blackIcon1 = ((ImageView) findViewById(R.id.blackIcon1));
24 | this.blackIcon2 = ((ImageView) findViewById(R.id.blackIcon2));
25 | this.brandIcon = ((ImageView) findViewById(R.id.brandIcon));
26 | this.geoIcon = ((ImageView) findViewById(R.id.geoIcon));
27 | // this.brandIcon.setVisibility(View.GONE);
28 | this.viewPointer = brandIcon;
29 | setVisible();
30 | }
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/ui/tag/TagViewRight.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.ui.tag;
2 |
3 | import com.example.jimageeditdemo.R;
4 |
5 | import android.content.Context;
6 | import android.util.AttributeSet;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | public class TagViewRight extends TagView {
13 | public TagViewRight(Context paramContext) {
14 | this(paramContext, null);
15 | }
16 |
17 | public TagViewRight(Context paramContext, AttributeSet paramAttributeSet) {
18 | super(paramContext, paramAttributeSet);
19 | LayoutInflater.from(paramContext).inflate(R.layout.tag_view_right, this);
20 | this.textview = ((TextView) findViewById(R.id.text));
21 | this.textview.getBackground().setAlpha(178);
22 | this.textview.setVisibility(View.VISIBLE);
23 | this.blackIcon1 = ((ImageView) findViewById(R.id.blackIcon1));
24 | this.blackIcon2 = ((ImageView) findViewById(R.id.blackIcon2));
25 | this.brandIcon = ((ImageView) findViewById(R.id.brandIcon));
26 | this.geoIcon = ((ImageView) findViewById(R.id.geoIcon));
27 | // this.brandIcon.setVisibility(View.GONE);
28 | this.viewPointer = brandIcon;
29 | setVisible();
30 | }
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/util/BitmapLoader.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.util;
2 |
3 | import android.content.ContentResolver;
4 | import android.content.Context;
5 | import android.content.res.Resources;
6 | import android.graphics.Bitmap;
7 | import android.graphics.BitmapFactory;
8 | import android.graphics.BitmapFactory.Options;
9 | import android.location.Location;
10 | import android.media.ExifInterface;
11 | import android.net.Uri;
12 | import android.text.TextUtils;
13 | import android.widget.ImageView;
14 | import java.io.FileNotFoundException;
15 | import java.io.IOException;
16 |
17 | public class BitmapLoader
18 | {
19 | /* public static int calculateInSampleSize(BitmapFactory.Options paramOptions, int paramInt1, int paramInt2)
20 | {
21 | int i = paramOptions.outHeight;
22 | int j = paramOptions.outWidth;
23 | int k = 1;
24 | if ((i > paramInt2) || (j > paramInt1))
25 | {
26 | int l = i / 2;
27 | int i1 = j / 2;
28 | while ((l / k > paramInt2) && (i1 / k > paramInt1))
29 | k *= 2;
30 | }
31 | return k;
32 | }*/
33 | /**
34 | * 计算压缩比例值
35 | * @param options 解析图片的配置信息
36 | * @param reqWidth 所需图片压缩尺寸最小宽度
37 | * @param reqHeight 所需图片压缩尺寸最小高度
38 | * @return
39 | */
40 | public static int calculateInSampleSize(BitmapFactory.Options options,
41 | int reqWidth, int reqHeight) {
42 | // 保存图片原宽高值
43 | final int height = options. outHeight;
44 | final int width = options. outWidth;
45 | // 初始化压缩比例为1
46 | int inSampleSize = 1;
47 |
48 | // 当图片宽高值任何一个大于所需压缩图片宽高值时,进入循环计算系统
49 | if (height > reqHeight || width > reqWidth) {
50 |
51 | final int halfHeight = height / 2;
52 | final int halfWidth = width / 2;
53 |
54 | // 压缩比例值每次循环两倍增加,
55 | // 直到原图宽高值的一半除以压缩值后都~大于所需宽高值为止
56 | while ((halfHeight / inSampleSize) >= reqHeight
57 | && (halfWidth / inSampleSize) >= reqWidth) {
58 | inSampleSize *= 2;
59 | }
60 | }
61 |
62 | return inSampleSize;
63 | }
64 |
65 | /*
66 | private static String dec2DMS(double paramDouble)
67 | {
68 | if (paramDouble > 0.0D);
69 | while (true)
70 | {
71 | String str1 = Integer.toString((int)paramDouble) + "/1,";
72 | double d1 = 60.0D * (paramDouble % 1.0D);
73 | String str2 = str1 + Integer.toString((int)d1) + "/1,";
74 | double d2 = 60000.0D * (d1 % 1.0D);
75 | return str2 + Integer.toString((int)d2) + "/1000";
76 | paramDouble = -paramDouble;
77 | }
78 | }*/
79 |
80 | /**
81 | * 获取压缩后的图片
82 | * @param res
83 | * @param resId
84 | * @param reqWidth 所需图片压缩尺寸最小宽度
85 | * @param reqHeight 所需图片压缩尺寸最小高度
86 | * @return
87 | */
88 | public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
89 | int reqWidth, int reqHeight) {
90 |
91 | // 首先不加载图片,仅获取图片尺寸
92 | final BitmapFactory.Options options = new BitmapFactory.Options();
93 | // 当inJustDecodeBounds设为true时,不会加载图片仅获取图片尺寸信息
94 | options.inJustDecodeBounds = true;
95 | // 此时仅会将图片信息会保存至options对象内,decode方法不会返回bitmap对象
96 | BitmapFactory.decodeResource(res, resId, options);
97 |
98 | // 计算压缩比例,如inSampleSize=4时,图片会压缩成原图的1/4
99 | options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
100 |
101 | // 当inJustDecodeBounds设为false时,BitmapFactory.decode...就会返回图片对象了
102 | options. inJustDecodeBounds = false;
103 | // 利用计算的比例值获取压缩后的图片对象
104 | return BitmapFactory.decodeResource(res, resId, options);
105 | }
106 |
107 |
108 | public static Bitmap decodeSampledBitmapFromUri(ContentResolver paramContentResolver, Uri paramUri, int paramInt1, int paramInt2)
109 | {
110 | BitmapFactory.Options localOptions = getBitmapOptions(paramContentResolver, paramUri);
111 | Bitmap localObject = null;
112 | if (localOptions != null)
113 | {
114 | localOptions.inSampleSize = calculateInSampleSize(localOptions, paramInt1, paramInt2);
115 | localOptions.inJustDecodeBounds = false;
116 | }
117 | try
118 | {
119 | Bitmap localBitmap = BitmapFactory.decodeStream(paramContentResolver.openInputStream(paramUri), null, localOptions);
120 | localObject = localBitmap;
121 | return localObject;
122 | }
123 | catch (FileNotFoundException localFileNotFoundException)
124 | {
125 | localFileNotFoundException.printStackTrace();
126 | }
127 | return null;
128 | }
129 |
130 | private static double dms2Dbl(String paramString)
131 | {
132 | double d1 = 999.0D;
133 | try
134 | {
135 | String[] arrayOfString1 = paramString.split(",", 3);
136 | String[] arrayOfString2 = arrayOfString1[0].split("/", 2);
137 | d1 = new Double(arrayOfString2[0]).doubleValue() / new Double(arrayOfString2[1]).doubleValue();
138 | String[] arrayOfString3 = arrayOfString1[1].split("/", 2);
139 | d1 += new Double(arrayOfString3[0]).doubleValue() / new Double(arrayOfString3[1]).doubleValue() / 60.0D;
140 | String[] arrayOfString4 = arrayOfString1[2].split("/", 2);
141 | double d2 = new Double(arrayOfString4[0]).doubleValue();
142 | double d3 = new Double(arrayOfString4[1]).doubleValue();
143 | return d1 + d2 / d3 / 3600.0D;
144 | }
145 | catch (Exception localException)
146 | {
147 | }
148 | return d1;
149 | }
150 |
151 | /*public static Location exif2Loc(String paramString)
152 | {
153 | Location localLocation = new Location("exif");
154 | int i = 1;
155 | String str1 = "";
156 | String str2 = "";
157 | double d1 = 0.0D;
158 | double d2 = 0.0D;
159 | try
160 | {
161 | ExifInterface localExifInterface = new ExifInterface(paramString);
162 | String str3 = localExifInterface.getAttribute("GPSLatitude");
163 | String str4 = localExifInterface.getAttribute("GPSLongitude");
164 | str1 = localExifInterface.getAttribute("GPSLatitudeRef");
165 | str2 = localExifInterface.getAttribute("GPSLongitudeRef");
166 | d1 = dms2Dbl(str3);
167 | if (d1 > 180.0D)
168 | i = 0;
169 | double d3 = dms2Dbl(str4);
170 | d2 = d3;
171 | if (d2 > 180.0D)
172 | i = 0;
173 | label110: if (i == 0)
174 | break label164;
175 | if (str1.contains("S"))
176 | d1 = -d1;
177 | if (str2.contains("W"))
178 | d2 = -d2;
179 | localLocation.setLatitude(d1);
180 | localLocation.setLongitude(d2);
181 | label164: return localLocation;
182 | }
183 | catch (IOException localIOException)
184 | {
185 | i = 0;
186 | break ;
187 | localLocation.setLatitude(Constant.GPS.lat);
188 | localLocation.setLongitude(Constant.GPS.lng);
189 | }
190 | return localLocation;
191 | }
192 | */
193 | public static BitmapFactory.Options getBitmapOptions(ContentResolver paramContentResolver, Uri paramUri)
194 | {
195 | BitmapFactory.Options localOptions = new BitmapFactory.Options();
196 | localOptions.inJustDecodeBounds = true;
197 | try
198 | {
199 | BitmapFactory.decodeStream(paramContentResolver.openInputStream(paramUri), null, localOptions);
200 | return localOptions;
201 | }
202 | catch (FileNotFoundException localFileNotFoundException)
203 | {
204 | localFileNotFoundException.printStackTrace();
205 | }
206 | return null;
207 | }
208 |
209 | private static int getExifOrientation(Uri paramUri)
210 | {
211 | try
212 | {
213 | int i = new ExifInterface(paramUri.getPath()).getAttributeInt("Orientation", 1);
214 | return i;
215 | }
216 | catch (Exception localException)
217 | {
218 | localException.printStackTrace();
219 | }
220 | return 1;
221 | }
222 |
223 | /* public static void loadFile(Context paramContext, String paramString1, String paramString2, ImageView paramImageView)
224 | {
225 | boolean bool = TextUtils.isEmpty(paramString1);
226 | int i = 0;
227 | if (bool);
228 | while (i != 0)
229 | {
230 | paramImageView.setImageResource(i);
231 | return;
232 | i = paramContext.getResources().getIdentifier(paramString1.substring(0, paramString1.indexOf(".")), "drawable", paramContext.getPackageName());
233 | }
234 | MatchaLoader.displayImage(paramString2, paramImageView);
235 | }*/
236 |
237 | /*public static void loc2Exif(Location paramLocation, String paramString)
238 | {
239 | if ((paramLocation != null) && (!TextUtils.isEmpty(paramString)));
240 | try
241 | {
242 | ExifInterface localExifInterface = new ExifInterface(paramString);
243 | localExifInterface.setAttribute("GPSLatitude", dec2DMS(paramLocation.getLatitude()));
244 | localExifInterface.setAttribute("GPSLongitude", dec2DMS(paramLocation.getLongitude()));
245 | if (paramLocation.getLatitude() > 0.0D)
246 | {
247 | localExifInterface.setAttribute("GPSLatitudeRef", "N");
248 | label63: if (paramLocation.getLongitude() <= 0.0D)
249 | break label96;
250 | localExifInterface.setAttribute("GPSLongitudeRef", "E");
251 | }
252 | while (true)
253 | {
254 | localExifInterface.saveAttributes();
255 | return;
256 | localExifInterface.setAttribute("GPSLatitudeRef", "S");
257 | break ;
258 | label96: localExifInterface.setAttribute("GPSLongitudeRef", "W");
259 | }
260 | return;
261 | }
262 | catch (IOException localIOException)
263 | {
264 | }
265 | }*/
266 | /*
267 | public static void loc2Exif(String paramString)
268 | {
269 | Location localLocation = new Location("exif");
270 | localLocation.setLatitude(Constant.GPS.lat);
271 | localLocation.setLongitude(Constant.GPS.lng);
272 | loc2Exif(localLocation, paramString);
273 | }*/
274 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/util/FileUtils.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.util;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 |
7 | import android.content.Context;
8 | import android.graphics.Bitmap;
9 | import android.graphics.Bitmap.CompressFormat;
10 | import android.graphics.BitmapFactory;
11 | import android.os.Environment;
12 |
13 | public class FileUtils {
14 | /**
15 | * sd卡的根目录
16 | */
17 | private static String mSdRootPath = Environment.getExternalStorageDirectory().getPath();
18 | /**
19 | * 手机的缓存根目录
20 | */
21 | private static String mDataRootPath = null;
22 | /**
23 | * 保存Image的目录名
24 | */
25 | private final static String FOLDER_NAME = "/LoveCity";
26 |
27 | private final static String IMAGE_NAME = "/cache";
28 |
29 | public FileUtils(Context context){
30 | mDataRootPath = context.getCacheDir().getPath();
31 | }
32 |
33 | public String makeAppDir(){
34 | String path = getStorageDirectory();
35 | File folderFile = new File(path);
36 | if(!folderFile.exists()){
37 | folderFile.mkdir();
38 | }
39 | path = path + IMAGE_NAME;
40 | folderFile = new File(path);
41 | if(!folderFile.exists()){
42 | folderFile.mkdir();
43 | }
44 | return path;
45 | }
46 |
47 | /**
48 | * 获取储存Image的目录
49 | * @return
50 | */
51 | private String getStorageDirectory(){
52 | return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ?
53 | mSdRootPath + FOLDER_NAME : mDataRootPath + FOLDER_NAME;
54 | }
55 |
56 | /**
57 | * 保存Image的方法,有sd卡存储到sd卡,没有就存储到手机目录
58 | * @param fileName
59 | * @param bitmap
60 | * @throws IOException
61 | */
62 | public void savaBitmap(String fileName, Bitmap bitmap) throws IOException{
63 | if(bitmap == null){
64 | return;
65 | }
66 | String path = getStorageDirectory();
67 |
68 |
69 | Logger.d("FileUtils", "savaBitmap path = " + path);
70 | Logger.d("FileUtils", "savaBitmap fileName = " + fileName);
71 | Logger.d("FileUtils", "savaBitmap mSdRootPath = " + mSdRootPath);
72 | Logger.d("FileUtils", "savaBitmap mDataRootPath = " + mDataRootPath);
73 | File folderFile = new File(path);
74 | if(!folderFile.exists()){
75 | folderFile.mkdir();
76 | }
77 | path = path + IMAGE_NAME;
78 | folderFile = new File(path);
79 | if(!folderFile.exists()){
80 | folderFile.mkdir();
81 | }
82 |
83 | File file = new File(path + File.separator + fileName);
84 | file.createNewFile();
85 | FileOutputStream fos = new FileOutputStream(file);
86 | bitmap.compress(CompressFormat.JPEG, 100, fos);
87 | fos.flush();
88 | fos.close();
89 | }
90 |
91 | /**
92 | * 从手机或者sd卡获取Bitmap
93 | * @param fileName
94 | * @return
95 | */
96 | public Bitmap getBitmap(String fileName){
97 | return BitmapFactory.decodeFile(getStorageDirectory() + File.separator + fileName);
98 | }
99 |
100 | /**
101 | * 判断文件是否存在
102 | * @param fileName
103 | * @return
104 | */
105 | public boolean isFileExists(String fileName){
106 | return new File(getStorageDirectory() + File.separator + fileName).exists();
107 | }
108 |
109 | /**
110 | * 获取文件的大小
111 | * @param fileName
112 | * @return
113 | */
114 | public long getFileSize(String fileName) {
115 | return new File(getStorageDirectory() + File.separator + fileName).length();
116 | }
117 |
118 |
119 | /**
120 | * 删除SD卡或者手机的缓存图片和目录
121 | */
122 | public void deleteFile() {
123 | File dirFile = new File(getStorageDirectory());
124 | if(! dirFile.exists()){
125 | return;
126 | }
127 | if (dirFile.isDirectory()) {
128 | String[] children = dirFile.list();
129 | for (int i = 0; i < children.length; i++) {
130 | new File(dirFile, children[i]).delete();
131 | }
132 | }
133 |
134 | dirFile.delete();
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/util/Logger.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.util;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | *
7 | * @Description: Log
8 | * @author jun
9 | * @date 2014-7-24 下午5:12:47
10 | *
11 | */
12 | public final class Logger {
13 |
14 | /** 日志级别 显示级别参考 android.util.Log的级别 配置0全部显示,配置大于7全不显示 */
15 | public static final int LEVLE = 2;
16 |
17 | public static void v(String tag, String msg) {
18 | if (LEVLE <= Log.VERBOSE)
19 | Log.v(tag, msg);
20 | }
21 |
22 | public static void v(String tag, String msg, Throwable tr) {
23 | if (LEVLE <= Log.VERBOSE)
24 | Log.v(tag, msg, tr);
25 | }
26 |
27 | public static void d(String tag, String msg) {
28 | if (LEVLE <= Log.DEBUG)
29 | Log.d(tag, msg);
30 | }
31 |
32 | public static void d(String tag, String msg, Throwable tr) {
33 | if (LEVLE <= Log.DEBUG)
34 | Log.d(tag, msg, tr);
35 | }
36 |
37 | public static void i(String tag, String msg) {
38 | if (LEVLE <= Log.INFO)
39 | Logger.d(tag, msg);
40 | }
41 |
42 | public static void i(String tag, String msg, Throwable tr) {
43 | if (LEVLE <= Log.INFO)
44 | Logger.d(tag, msg, tr);
45 | }
46 |
47 | public static void w(String tag, String msg) {
48 | if (LEVLE <= Log.WARN)
49 | Log.w(tag, msg);
50 | }
51 |
52 | public static void w(String tag, String msg, Throwable tr) {
53 | if (LEVLE <= Log.WARN)
54 | Log.w(tag, msg, tr);
55 | }
56 |
57 | public static void w(String tag, Throwable tr) {
58 | if (LEVLE <= Log.WARN)
59 | Log.w(tag, tr.getMessage(), tr);
60 | }
61 |
62 | public static void e(String tag, String msg) {
63 | if (LEVLE <= Log.ERROR)
64 | Log.e(tag, msg);
65 | }
66 |
67 | public static void e(String tag, String msg, Throwable tr) {
68 | if (LEVLE <= Log.ERROR)
69 | Log.e(tag, msg, tr);
70 | }
71 |
72 | public static void e(String tag, Throwable tr) {
73 | if (LEVLE <= Log.ERROR)
74 | Log.e(tag, tr.getMessage(), tr);
75 | }
76 |
77 | public static void wtf(String tag, String msg) {
78 | if (LEVLE <= Log.ASSERT)
79 | Log.wtf(tag, msg);
80 | }
81 |
82 | public static void wtf(String tag, Throwable tr) {
83 | if (LEVLE <= Log.ASSERT)
84 | Log.wtf(tag, tr);
85 | }
86 |
87 | public static void wtf(String tag, String msg, Throwable tr) {
88 | if (LEVLE <= Log.ASSERT)
89 | Logger.wtf(tag, msg, tr);
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pmmq/pmmqproject/util/NormalUtils.java:
--------------------------------------------------------------------------------
1 | package com.pmmq.pmmqproject.util;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 | import java.io.OutputStream;
7 |
8 | import android.graphics.Bitmap;
9 | import android.text.TextPaint;
10 |
11 | public class NormalUtils {
12 |
13 | /**
14 | * 获取字符串显示宽度,与字体有关
15 | * @param text
16 | * @param Size
17 | * @return
18 | */
19 | public static float GetTextWidth(String text, float Size) {
20 | //第一个参数是要计算的字符串,第二个参数是字提大小
21 | TextPaint FontPaint = new TextPaint();
22 | FontPaint.setTextSize(Size);
23 | return FontPaint.measureText(text);
24 | }
25 |
26 | /**
27 | * 将Bitmap放入缓存,
28 | * @Title: saveDrawableToCache
29 | * @param bitmap
30 | * @param filePath
31 | * @return void
32 | * @date 2012-12-14 上午9:27:38
33 | */
34 | public void saveDrawableToCache(Bitmap bitmap, String filePath){
35 |
36 | try {
37 | File file = new File(filePath);
38 |
39 | file.createNewFile();
40 |
41 | OutputStream outStream = new FileOutputStream(file);
42 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
43 | outStream.flush();
44 | outStream.close();
45 |
46 | } catch (IOException e) {
47 |
48 | e.printStackTrace();
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/black_anim.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/white_anim.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
15 |
25 |
35 |
45 |
55 |
56 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/brand_tag_point_black_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/brand_tag_point_black_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/brand_tag_point_white_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/brand_tag_point_white_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/camera_crop_height.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/camera_crop_height.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/camera_crop_width.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/camera_crop_width.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/icon_place.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/icon_place.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/icon_tag_brand_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/icon_tag_brand_active.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/icon_tag_brand_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/icon_tag_brand_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/icon_tag_geolocation_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/icon_tag_geolocation_active.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/icon_tag_geolocation_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/icon_tag_geolocation_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/icon_tag_user_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/icon_tag_user_active.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/icon_tag_user_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/icon_tag_user_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/indicator_autocrop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/indicator_autocrop.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/tag_text_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/tag_text_bg.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/tag_text_bg_left.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/tag_text_bg_left.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/tag_text_bg_right.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/tag_text_bg_right.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/wm_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/wm_1.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/wm_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/wm_2.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/wm_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/wm_3.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/wm_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/wm_4.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/wm_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/wm_5.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/wm_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-hdpi/wm_6.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/huishu.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-xhdpi/huishu.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_add_tag.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
17 |
23 |
24 |
33 |
41 |
49 |
56 |
57 |
58 |
59 |
60 |
61 |
70 |
75 |
82 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_crop.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
20 |
21 |
25 |
26 |
27 |
36 |
37 |
45 |
46 |
53 |
54 |
61 |
62 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_pre_view.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_show_tag.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_take_pic.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_water_mark.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
14 |
20 |
21 |
22 |
31 |
32 |
39 |
40 |
47 |
48 |
55 |
56 |
57 |
58 |
59 |
67 |
68 |
75 |
76 |
83 |
84 |
91 |
92 |
93 |
94 |
95 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_water_mark_image_filter.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
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 |
58 |
59 |
64 |
65 |
69 |
70 |
77 |
78 |
84 |
85 |
86 |
90 |
91 |
97 |
98 |
104 |
105 |
106 |
110 |
111 |
117 |
118 |
124 |
125 |
126 |
130 |
131 |
137 |
138 |
144 |
145 |
146 |
150 |
151 |
157 |
158 |
164 |
165 |
166 |
170 |
171 |
177 |
178 |
184 |
185 |
186 |
190 |
191 |
197 |
198 |
204 |
205 |
206 |
210 |
211 |
217 |
218 |
224 |
225 |
226 |
230 |
231 |
237 |
238 |
244 |
245 |
246 |
247 |
248 |
249 |
257 |
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_main.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tag_view_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
22 |
23 |
31 |
32 |
40 |
41 |
49 |
50 |
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tag_view_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
26 |
27 |
43 |
44 |
54 |
55 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 | 64dp
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ff00ff
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 | 100dp
7 | 5dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | JImageEditDemo
5 | Hello world!
6 | Settings
7 |
8 |
9 |
10 | 下一步
11 | 旋转
12 | 取消
13 | 请稍后...
14 | 添加标签
15 |
16 |
17 | 您要删除当前标签吗 ?
18 | 确定
19 | 取消
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/test/java/com/example/jimageeditdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.jimageeditdemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.0.0-alpha3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiushi123/AndroidtagView/106c158947167ca173933e9f34a9949c9bc1b440/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Oct 21 11:34:03 PDT 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------