├── .gitignore
├── .idea
├── .gitignore
├── .name
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── compiler.xml
├── gradle.xml
├── jarRepositories.xml
├── misc.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
├── release
│ ├── app-release.apk
│ └── output-metadata.json
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── zero_code
│ │ └── editimage
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── zero_code
│ │ │ └── editimage
│ │ │ ├── GlideEngine.java
│ │ │ └── MainActivity.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_launcher_background.xml
│ │ └── test.jpg
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── values-night
│ │ └── themes.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ └── test
│ └── java
│ └── com
│ └── zero_code
│ └── editimage
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── lib_edImage
├── .gitignore
├── aar
│ └── lib_edImage-release.aar
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── zero_code
│ │ │ └── libEdImage
│ │ │ ├── EditImageView.kt
│ │ │ ├── ImageConfig.kt
│ │ │ ├── adapter
│ │ │ ├── BaseAdapter.kt
│ │ │ ├── BaseRecyclerAdapter.java
│ │ │ ├── adapter.kt
│ │ │ └── animation.kt
│ │ │ ├── anim
│ │ │ └── EditHomingAnimator.java
│ │ │ ├── clip
│ │ │ ├── EditClip.java
│ │ │ ├── EditClipWindow.java
│ │ │ └── EditImageViewPortrait.kt
│ │ │ ├── core
│ │ │ ├── EditImage.kt
│ │ │ ├── EditImageArrows.kt
│ │ │ ├── EditImageMode.kt
│ │ │ └── EditImagePath.kt
│ │ │ ├── elastic
│ │ │ ├── EditElastic.java
│ │ │ ├── EditElasticAnimator.kt
│ │ │ ├── EditPointFEvaluator.kt
│ │ │ └── EditRectFEvaluator.kt
│ │ │ ├── extend.kt
│ │ │ ├── homing
│ │ │ ├── EditHoming.java
│ │ │ └── EditHomingEvaluator.java
│ │ │ ├── model
│ │ │ └── ClipViewModel.kt
│ │ │ ├── sticker
│ │ │ ├── EditSticker.kt
│ │ │ ├── EditStickerHelper.java
│ │ │ ├── EditStickerMoveHelper.kt
│ │ │ ├── EditStickerPortrait.kt
│ │ │ └── EditStickerX.java
│ │ │ ├── ui
│ │ │ ├── EditImageActivity.kt
│ │ │ └── text
│ │ │ │ ├── EditImageText.kt
│ │ │ │ └── EditTextEditDialog.java
│ │ │ ├── util
│ │ │ ├── IMGUtils.java
│ │ │ └── StatusBarUtil.java
│ │ │ ├── view
│ │ │ ├── Bean.kt
│ │ │ ├── EditColorGroup.java
│ │ │ ├── EditColorRadio.java
│ │ │ ├── EditMosaicGroup.java
│ │ │ ├── EditMosaicRadio.java
│ │ │ └── PathArrows.kt
│ │ │ └── widget
│ │ │ ├── EditStickerAdjustHelper.java
│ │ │ ├── EditStickerTextView.java
│ │ │ └── EditStickerView.java
│ └── res
│ │ ├── anim
│ │ ├── image_dialog_enter.xml
│ │ ├── image_dialog_exit.xml
│ │ ├── image_fade_in.xml
│ │ └── image_fade_out.xml
│ │ ├── color
│ │ └── image_color_text.xml
│ │ ├── layout
│ │ ├── activity_edit_image.xml
│ │ ├── app_item_null.xml
│ │ ├── image_arrows_layout.xml
│ │ ├── image_color_layout.xml
│ │ ├── image_mosaic_layout.xml
│ │ ├── image_text_dialog.xml
│ │ └── item_edit_image_tools_layout.xml
│ │ ├── mipmap-hdpi
│ │ ├── btn_ed_arrow.png
│ │ ├── btn_ed_arrowed.png
│ │ ├── btn_ed_close.png
│ │ ├── btn_ed_cut.png
│ │ ├── btn_ed_cuted.png
│ │ ├── btn_ed_free.png
│ │ ├── btn_ed_freed.png
│ │ ├── btn_ed_left.png
│ │ ├── btn_ed_level.png
│ │ ├── btn_ed_mosaic.png
│ │ ├── btn_ed_mosaic2.png
│ │ ├── btn_ed_mosaiced.png
│ │ ├── btn_ed_ok.png
│ │ ├── btn_ed_plumb.png
│ │ ├── btn_ed_right.png
│ │ ├── btn_ed_text.png
│ │ ├── btn_ed_texted.png
│ │ ├── btn_ed_texts.png
│ │ └── btn_ed_undo.png
│ │ ├── mipmap-mdpi
│ │ ├── btn_ed_arrow.png
│ │ ├── btn_ed_arrowed.png
│ │ ├── btn_ed_close.png
│ │ ├── btn_ed_cut.png
│ │ ├── btn_ed_cuted.png
│ │ ├── btn_ed_free.png
│ │ ├── btn_ed_freed.png
│ │ ├── btn_ed_left.png
│ │ ├── btn_ed_level.png
│ │ ├── btn_ed_mosaic.png
│ │ ├── btn_ed_mosaic2.png
│ │ ├── btn_ed_mosaiced.png
│ │ ├── btn_ed_ok.png
│ │ ├── btn_ed_plumb.png
│ │ ├── btn_ed_right.png
│ │ ├── btn_ed_text.png
│ │ ├── btn_ed_texted.png
│ │ ├── btn_ed_texts.png
│ │ └── btn_ed_undo.png
│ │ ├── mipmap-xhdpi
│ │ ├── btn_ed_arrow.png
│ │ ├── btn_ed_arrowed.png
│ │ ├── btn_ed_close.png
│ │ ├── btn_ed_cut.png
│ │ ├── btn_ed_cuted.png
│ │ ├── btn_ed_free.png
│ │ ├── btn_ed_freed.png
│ │ ├── btn_ed_left.png
│ │ ├── btn_ed_level.png
│ │ ├── btn_ed_mosaic.png
│ │ ├── btn_ed_mosaic2.png
│ │ ├── btn_ed_mosaiced.png
│ │ ├── btn_ed_ok.png
│ │ ├── btn_ed_plumb.png
│ │ ├── btn_ed_right.png
│ │ ├── btn_ed_text.png
│ │ ├── btn_ed_texted.png
│ │ ├── btn_ed_texts.png
│ │ ├── btn_ed_undo.png
│ │ ├── image_ic_adjust.png
│ │ └── image_ic_delete.png
│ │ ├── mipmap-xxhdpi
│ │ ├── btn_ed_arrow.png
│ │ ├── btn_ed_arrowed.png
│ │ ├── btn_ed_close.png
│ │ ├── btn_ed_cut.png
│ │ ├── btn_ed_cuted.png
│ │ ├── btn_ed_free.png
│ │ ├── btn_ed_freed.png
│ │ ├── btn_ed_left.png
│ │ ├── btn_ed_level.png
│ │ ├── btn_ed_mosaic.png
│ │ ├── btn_ed_mosaic2.png
│ │ ├── btn_ed_mosaiced.png
│ │ ├── btn_ed_ok.png
│ │ ├── btn_ed_plumb.png
│ │ ├── btn_ed_right.png
│ │ ├── btn_ed_text.png
│ │ ├── btn_ed_texted.png
│ │ ├── btn_ed_texts.png
│ │ ├── btn_ed_undo.png
│ │ ├── image_ic_adjust.png
│ │ └── image_ic_delete.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── btn_ed_arrow.png
│ │ ├── btn_ed_arrowed.png
│ │ ├── btn_ed_close.png
│ │ ├── btn_ed_cut.png
│ │ ├── btn_ed_cuted.png
│ │ ├── btn_ed_free.png
│ │ ├── btn_ed_freed.png
│ │ ├── btn_ed_left.png
│ │ ├── btn_ed_level.png
│ │ ├── btn_ed_mosaic.png
│ │ ├── btn_ed_mosaic2.png
│ │ ├── btn_ed_mosaiced.png
│ │ ├── btn_ed_ok.png
│ │ ├── btn_ed_plumb.png
│ │ ├── btn_ed_right.png
│ │ ├── btn_ed_text.png
│ │ ├── btn_ed_texted.png
│ │ ├── btn_ed_texts.png
│ │ ├── btn_ed_undo.png
│ │ ├── image_ic_adjust.png
│ │ └── image_ic_delete.png
│ │ ├── values-v21
│ │ └── styles.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── ids.xml
│ │ ├── image_attrs.xml
│ │ ├── image_colors.xml
│ │ ├── image_dimens.xml
│ │ ├── image_strings.xml
│ │ ├── image_styles.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── zero_code
│ └── libEdImage
│ └── ExampleUnitTest.java
├── resource
└── 051600390884_02b7403e8a39a37fa630e48cddd9909a.jpg
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | EditImage
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | xmlns:android
18 |
19 | ^$
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | xmlns:.*
29 |
30 | ^$
31 |
32 |
33 | BY_NAME
34 |
35 |
36 |
37 |
38 |
39 |
40 | .*:id
41 |
42 | http://schemas.android.com/apk/res/android
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | .*:name
52 |
53 | http://schemas.android.com/apk/res/android
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | name
63 |
64 | ^$
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | style
74 |
75 | ^$
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | .*
85 |
86 | ^$
87 |
88 |
89 | BY_NAME
90 |
91 |
92 |
93 |
94 |
95 |
96 | .*
97 |
98 | http://schemas.android.com/apk/res/android
99 |
100 |
101 | ANDROID_ATTRIBUTE_ORDER
102 |
103 |
104 |
105 |
106 |
107 |
108 | .*
109 |
110 | .*
111 |
112 |
113 | BY_NAME
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.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 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🔥🔥🔥EditImage🔥🔥🔥
2 |
3 | ## 介绍
4 |
5 | 🔥🔥🔥基于canvas画布,实现的一款图片轻量级编辑框架,目前支持涂鸦、马赛克、剪裁、文字功能
6 |
7 |
8 | 
9 |
10 |
11 |
12 | ## TODO
13 | 1. 小概率剪裁框偏差
14 | 2. 动画
15 | 3. 文字边框小概率缩小
16 |
17 |
18 |
19 | ## 集成
20 |
21 |
22 | [](https://jitpack.io/#OneZeroYang/EditImage)
23 |
24 | ##### 1. 权限
25 |
26 |
27 |
28 |
29 | 在`AndroidManifest.xml`的`manifest`节点下添加:
30 |
31 | 如下:
32 |
33 | ````xml
34 |
35 |
36 |
37 | ````
38 |
39 | 注意:Android6.0及以上需要动态权限验证
40 |
41 | ````
42 | private fun checkPermission() {
43 | //申请权限(Android6.0及以上 需要动态申请危险权限)
44 | if (ContextCompat.checkSelfPermission(
45 | this,
46 | Manifest.permission.WRITE_EXTERNAL_STORAGE
47 | ) != PackageManager.PERMISSION_GRANTED
48 | ) {
49 | //申请权限
50 | ActivityCompat.requestPermissions(
51 | this, arrayOf(
52 | Manifest.permission.WRITE_EXTERNAL_STORAGE,
53 | Manifest.permission.READ_EXTERNAL_STORAGE
54 | ), checkPermissionCode
55 | )
56 | } else {
57 | // 获取权限成功
58 | }
59 | }
60 | ````
61 |
62 | ##### 2. 在项目根目录下`build.gradle`文件中 添加
63 |
64 |
65 | maven { url 'https://jitpack.io' }
66 |
67 |
68 | 如下:
69 | ````
70 | allprojects {
71 | repositories {
72 | ...
73 | maven { url 'https://jitpack.io' }
74 | }
75 | }
76 | ````
77 |
78 |
79 |
80 | ##### 3. 在`app`目录下`build.gradle`文件中添加
81 |
82 | implementation 'com.github.OneZeroYang:EditImage:Tag'
83 |
84 | 如下:
85 | ````
86 | dependencies {
87 | implementation 'com.github.OneZeroYang:EditImage:1.1.0'
88 | }
89 | ````
90 |
91 | ## 注意
92 |
93 | 1. 项目本身最低版本为api19 android 4.4及以上(最低适配版本为4.4)
94 | 2. 如果要使用本库的UI,依赖项目必须开启dataBinding
95 |
96 | 在`app`的`build.gradle`下 `android` 节点下添加如下代码
97 | ````
98 | dataBinding {
99 | enabled = true
100 | }
101 | ````
102 |
103 |
104 |
105 | ## 使用
106 |
107 | ##### 1. 快速使用
108 | kotlin:
109 | api
110 | ````
111 | /**
112 | * 开始编辑图片
113 | * @param src 资源 可以是本地图片 支持 uri path 不支持网络图片
114 | * @param onError 错误的回调
115 | */
116 | fun Activity.startEditImage(
117 | src: Any,
118 | requestCode: Int,
119 | onError: ((Exception) -> Unit)? = null
120 | )
121 |
122 | ````
123 |
124 | 1. startEditImage(uri,requestCode)
125 |
126 |
127 | 2. 在activity实现`onActivityResult`方法
128 |
129 | ````
130 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
131 | super.onActivityResult(requestCode, resultCode, data)
132 | if (requestCode == requestCode && resultCode == Activity.RESULT_OK) {
133 | val filePath = data?.getStringExtra("data") //返回结果
134 | }
135 | }
136 | ````
137 |
138 |
139 |
140 | 注:目前快速使用仅支持kotlin,java请前往`定制化`
141 |
142 |
143 | ##### 2. 定制化
144 |
145 | ###### 基础
146 |
147 | 1. 核心`EditImageView`
148 | 完全使用自定义`view`实现
149 |
150 | 2. 模式
151 | NONE, //默认
152 | DOODLE, //涂鸦
153 | MOSAIC, //马赛克
154 | CLIP, //剪裁
155 | ARROWS //箭头
156 |
157 | 3. 文字/表情/贴图
158 | EditStickerView
159 |
160 | ###### 开始
161 |
162 | 1. 新建一个Activity/Fragment
163 |
164 | 2. 在布局文件里面添加`EditImageView`并初始化
165 |
166 | ````
167 |
172 | ````
173 | 注意:`EditImageView` 得 `background` 必须为全黑色不透明
174 |
175 | 3. 初始化控件
176 |
177 | ````
178 | val mEditView : EditImageView? =null
179 | mEditView=findViewById(R.id.mEditView)
180 | ````
181 |
182 | 4. 设置编辑模式
183 | ````
184 | mEditView.mode = EditImageMode.NONE//预览模式
185 | mEditView.mode = EditImageMode.DOODLE//涂鸦模式
186 | mEditView.mode = EditImageMode.MOSAIC//马塞克模式
187 | mEditView.mode = EditImageMode.CLIP//裁剪模式
188 | mEditView.mode = EditImageMode.ARROWS//箭头模式
189 |
190 | ````
191 |
192 | 注意:当需要添加自定义控件得时候,需要设置模式为预览模式,并调用`addStickerView`,详情见`添加自定义View`
193 |
194 | 5. 预览模式
195 |
196 | 当模式为`EditImageMode.NONE` 时
197 | 预览模式仅支持图片得预览和添加自定义View,包括移动,放大缩小
198 |
199 | 6. 涂鸦
200 |
201 | 当模式为` EditImageMode.DOODLE` 时
202 |
203 | 设置涂鸦颜色:
204 |
205 | ````
206 | mEditView.setPenColor(color)
207 | ````
208 |
209 | 撤销上一步涂鸦
210 |
211 | ````
212 | mEditView.undoDoodle()
213 | ````
214 |
215 | 7. 马赛克
216 |
217 | 当模式为` EditImageMode.MOSAIC` 时
218 |
219 | 设置马赛克大小
220 |
221 | ````
222 | mEditView.setMosaicWidth(size)
223 | ````
224 |
225 |
226 | 撤销上一步马赛克
227 |
228 | ````
229 | mEditView.undoMosaic()
230 | ````
231 |
232 | 马赛克大小预设0.2f-0.6f之间
233 |
234 | ````
235 | public static final Float IMG_MOSAIC_SIZE_1=0.2F;
236 | public static final Float IMG_MOSAIC_SIZE_2=0.3F;
237 | public static final Float IMG_MOSAIC_SIZE_3=0.4F;
238 | public static final Float IMG_MOSAIC_SIZE_4=0.5F;
239 | public static final Float IMG_MOSAIC_SIZE_5=0.6F;
240 |
241 | ````
242 |
243 | 8. 裁剪
244 |
245 | 当模式为` EditImageMode.CLIP` 时
246 |
247 | 裁剪模式不仅包含裁剪,同时还支持旋转和镜面翻转
248 |
249 | 旋转
250 |
251 |
252 | ````
253 | mEditView.doRotate(-90f) //left 旋转90°
254 | mEditView.doRotate(90f) //Right 旋转90°
255 | ````
256 |
257 |
258 |
259 | 镜面翻转
260 |
261 | ````
262 | mEditView.doVerticalMirror() //垂直镜面反转
263 | mEditView.doHorizontalMirror() //水平镜像反转
264 | ````
265 |
266 | 取消裁剪
267 |
268 | ````
269 | mEditView.cancelClip()
270 | ````
271 |
272 | 重置裁剪
273 |
274 | ````
275 | mEditView.resetClip()
276 | ````
277 |
278 | 注意:重置裁剪只会对裁剪部分重置,不会对翻转/旋转生效,对翻转/旋转生效需要自行实现,请参考`com.zero_code.libEdImage.ui.EditImageActivity`源码
279 |
280 |
281 | 确认裁剪
282 |
283 | ````
284 | mEditView.doClip()
285 | ````
286 |
287 | 9. 箭头模式
288 |
289 | 当模式为` EditImageMode.ARROWS` 时
290 |
291 | 设置箭头大小
292 |
293 | ````
294 | mEditView.setArrowsSize(size)
295 | ````
296 | 注意:箭头大小内置预设为5个等级 1-5
297 |
298 | 设置箭头颜色
299 |
300 | ````
301 | mEditView.setArrowsColor(color)
302 | ````
303 |
304 | 撤销上一步箭头
305 |
306 | ````
307 | mEditView.clearLastArrows()
308 | ````
309 |
310 | 10. 对保存编辑搞得图片保存为bitmap
311 |
312 | ````
313 | mEditView.mEditView.saveBitmap()
314 | ````
315 |
316 |
317 | ## 添加自定义View
318 |
319 | 请自行下载源码查看
320 |
321 | ## 其他api
322 |
323 | 请自行下载源码查看
324 |
325 |
326 | ## 混淆
327 |
328 | ````
329 | # editImage
330 | -keep public class com.zero_code.libEdImage.EditImageView
331 | -keep public class com.zero_code.libEdImage.core.EditImageMode
332 | -keep class com.zero_code.libEdImage.widget.** { *; }
333 | -keep class com.zero_code.libEdImage.view.** { *; }
334 | ````
335 |
336 | ## 关于
337 | 如在使用过程中出现任何问题或者BUG,欢迎各位小伙伴提供宝贵得意见
338 | 如果您喜欢这个项目,动动您得小手帮忙点一个star,您的支持,是我前进的最大的动力
339 | QQ:1819405190(添加时,备注 "EditImageView")
340 |
341 |
342 |
343 | ## 测试
344 |
345 | 测试机型 vivo iooq neo 855版本
346 | Android 10
347 | 内存8G
348 |
349 | 1. 自测基本没有致命性异常
350 | 2. 内存根据图片分辨率、大小有所不同,目前编辑3264x2448 分辨率图片最大内存峰值在600M左右,连续快速旋转、翻转会有一定的内存抖动,但不影响正常使用
351 | 3. 使用Android Studio自带内存检测工具没有发现内存泄露的情况
352 |
353 | ## 感谢
354 | felix 核心实现参考
355 |
356 |
357 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'kotlin-android'
4 | id 'kotlin-kapt'
5 | id 'kotlin-android-extensions'
6 | }
7 | def room_version = "2.2.0-rc01"
8 | android {
9 | compileSdkVersion 30
10 | buildToolsVersion "30.0.3"
11 |
12 | defaultConfig {
13 | applicationId "com.batchat.editimage"
14 | minSdkVersion 19
15 | targetSdkVersion 30
16 | versionCode 1
17 | versionName "1.0"
18 |
19 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
20 | }
21 |
22 | buildTypes {
23 | release {
24 | minifyEnabled true
25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26 | }
27 | debug {
28 | minifyEnabled true
29 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
30 | }
31 | }
32 | compileOptions {
33 | sourceCompatibility JavaVersion.VERSION_1_8
34 | targetCompatibility JavaVersion.VERSION_1_8
35 | }
36 | kotlinOptions {
37 | jvmTarget = '1.8'
38 | }
39 |
40 | dataBinding {
41 | enabled = true
42 | }
43 | }
44 |
45 | dependencies {
46 |
47 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
48 | implementation 'androidx.core:core-ktx:1.2.0'
49 | implementation 'androidx.appcompat:appcompat:1.1.0'
50 | implementation 'com.google.android.material:material:1.1.0'
51 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
52 | implementation project(path: ':lib_edImage')
53 | testImplementation 'junit:junit:4.+'
54 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
55 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
56 |
57 | implementation "androidx.room:room-runtime:$room_version"
58 | // For Kotlin use kapt instead of annotationProcessor (注意这个注释)
59 | kapt "androidx.room:room-compiler:$room_version"
60 |
61 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
62 |
63 |
64 |
65 | implementation 'com.github.bumptech.glide:glide:4.12.0'
66 | annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
67 | // implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.5.9'
68 |
69 | implementation 'com.github.HuanTanSheng:EasyPhotos:3.1.3'
70 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
23 |
24 | #安卓默认会删除一些无用的包,可以用dontshrink来禁止这种行为。
25 | -dontshrink
26 | #不进行优化,建议使用此选项
27 | -dontoptimize
28 | # 屏蔽警告
29 | -ignorewarnings
30 | # 不预校验,加快混淆速度
31 | -dontpreverify
32 | #@Autowired 装配失败的问题
33 | -keepdirectories
34 | #保持packagename 不混淆
35 | -flattenpackagehierarchy
36 | -allowaccessmodification
37 | # 指定不去忽略非公共的库类(不跳过library中的非public的类)
38 | -dontskipnonpubliclibraryclasses
39 | # 指定不去忽略包可见的库类的成员
40 | -dontskipnonpubliclibraryclassmembers
41 | # 指定混淆是采用的算法,后面的参数是一个过滤器
42 | # 这个过滤器是谷歌推荐的算法,一般不做更改
43 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
44 | # 抛出异常时保留代码行号
45 | -keepattributes Exceptions,InnerClasses,Signature,SourceFile,LineNumberTable
46 | # 混淆时记录日志(打印混淆的详细信息)
47 | # 这句话能够使我们的项目混淆后产生映射文件
48 | # 包含有类名->混淆后类名的映射关系
49 | -verbose
50 |
51 | -dontwarn com.google.android.maps.**
52 | -dontwarn android.webkit.WebView
53 | -dontwarn com.umeng.**
54 | -dontwarn com.tencent.weibo.sdk.**
55 | -keep public class javax.**
56 | -keep public class android.webkit.**
57 | -dontwarn android.support.v4.**
58 | -keepattributes SourceFile,LineNumberTable
59 |
60 | #kotlin
61 | -keep class kotlin.** { *; }
62 | -keep class kotlin.Metadata { *; }
63 | -dontwarn kotlin.**
64 | -keepclassmembers class **$WhenMappings {
65 | ;
66 | }
67 | -keepclassmembers class kotlin.Metadata {
68 | public ;
69 | }
70 | -assumenosideeffects class kotlin.jvm.internal.Intrinsics {
71 | static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
72 | }
73 |
74 | -keepclasseswithmembernames class * {
75 | native ;
76 | }
77 |
78 | -keepclassmembers class * extends android.app.Activity {
79 | public void *(android.view.View);
80 | }
81 | -keepclassmembers class * implements android.os.Parcelable {
82 | public static final android.os.Parcelable$Creator *;
83 | }
84 | -keep class **.R$* {*;}
85 | -keepclassmembers enum * { *;}
86 |
87 | -keep public class * extends android.app.Activity
88 | -keep public class * extends android.app.Application
89 | -keep public class * extends android.app.Service
90 | -keep public class * extends android.content.BroadcastReceiver
91 | -keep public class * extends android.content.ContentProvider
92 | -keep public class * extends android.app.backup.BackupAgentHelper
93 | -keep public class * extends android.preference.Preference
94 |
95 | #AndroidX混淆规则
96 | -keep class com.google.android.material.** {*;}
97 | -keep class androidx.** {*;}
98 | -keep public class * extends androidx.*
99 | -keep interface androidx.** {*;}
100 | -dontwarn com.google.android.material.**
101 | -dontnote com.google.android.material.**
102 | -dontwarn androidx.**
103 |
104 | #Glide START
105 | -keep public class * implements com.bumptech.glide.module.GlideModule
106 | -keep class * extends com.bumptech.glide.module.AppGlideModule {
107 | (...);
108 | }
109 | -keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
110 | **[] $VALUES;
111 | public *;
112 | }
113 | -keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
114 | *** rewind();
115 | }
116 | # for DexGuard only
117 | #-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
118 |
119 | #Glide END
120 |
121 |
122 | #PictureSelector 2.0
123 | -keep class com.luck.picture.lib.** { *; }
124 |
125 | -keep class com.huantansheng.easyphotos.models.** { *; }
126 |
127 |
128 |
129 | # editImage
130 | -keep public class com.zero_code.libEdImage.EditImageView
131 | -keep public class com.zero_code.libEdImage.core.EditImageMode
132 | -keep class com.zero_code.libEdImage.widget.** { *; }
133 | -keep class com.zero_code.libEdImage.view.** { *; }
134 |
135 |
--------------------------------------------------------------------------------
/app/release/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/release/app-release.apk
--------------------------------------------------------------------------------
/app/release/output-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "artifactType": {
4 | "type": "APK",
5 | "kind": "Directory"
6 | },
7 | "applicationId": "com.batchat.editimage",
8 | "variantName": "processReleaseResources",
9 | "elements": [
10 | {
11 | "type": "SINGLE",
12 | "filters": [],
13 | "versionCode": 1,
14 | "versionName": "1.0",
15 | "outputFile": "app-release.apk"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/zero_code/editimage/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.editimage
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.batchat.editimage", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zero_code/editimage/GlideEngine.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.editimage;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.PointF;
6 | import android.graphics.drawable.Drawable;
7 | import android.net.Uri;
8 | import android.view.View;
9 | import android.widget.ImageView;
10 |
11 | import androidx.annotation.NonNull;
12 | import androidx.annotation.Nullable;
13 | import androidx.core.graphics.drawable.RoundedBitmapDrawable;
14 | import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
15 |
16 | import com.bumptech.glide.Glide;
17 | import com.bumptech.glide.request.RequestOptions;
18 | import com.bumptech.glide.request.target.BitmapImageViewTarget;
19 | import com.bumptech.glide.request.target.ImageViewTarget;
20 | import com.huantansheng.easyphotos.engine.ImageEngine;
21 |
22 |
23 | /**
24 | * @author:luck
25 | * @date:2019-11-13 17:02
26 | * @describe:Glide加载引擎
27 | */
28 | public class GlideEngine implements ImageEngine {
29 |
30 |
31 |
32 |
33 |
34 |
35 | private GlideEngine() {
36 | }
37 |
38 | private static GlideEngine instance;
39 |
40 | public static GlideEngine createGlideEngine() {
41 | if (null == instance) {
42 | synchronized ( GlideEngine.class) {
43 | if (null == instance) {
44 | instance = new GlideEngine();
45 | }
46 | }
47 | }
48 | return instance;
49 | }
50 |
51 | @Override
52 | public void loadPhoto(@NonNull Context context, @NonNull Uri uri, @NonNull ImageView imageView) {
53 | Glide.with(context)
54 | .load(uri)
55 | .override(200, 200)
56 | .centerCrop()
57 |
58 | .into(imageView);
59 | }
60 |
61 | @Override
62 | public void loadGifAsBitmap(@NonNull Context context, @NonNull Uri gifUri, @NonNull ImageView imageView) {
63 | Glide.with(context)
64 | .load(gifUri)
65 | .override(200, 200)
66 | .centerCrop()
67 | .into(imageView);
68 | }
69 |
70 | @Override
71 | public void loadGif(@NonNull Context context, @NonNull Uri gifUri, @NonNull ImageView imageView) {
72 | Glide.with(context)
73 | .load(gifUri)
74 | .override(200, 200)
75 | .centerCrop()
76 | .into(imageView);
77 | }
78 |
79 | @Override
80 | public Bitmap getCacheBitmap(@NonNull Context context, @NonNull Uri uri, int width, int height) throws Exception {
81 | return Glide.with(context).asBitmap().submit().get();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zero_code/editimage/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.editimage
2 |
3 | import android.R.attr
4 | import android.app.Activity
5 | import android.content.Intent
6 | import android.graphics.Bitmap
7 | import android.os.Bundle
8 | import android.util.Log
9 | import android.view.View
10 | import androidx.appcompat.app.AppCompatActivity
11 | import com.bumptech.glide.Glide
12 | import com.huantansheng.easyphotos.EasyPhotos
13 | import com.huantansheng.easyphotos.models.album.entity.Photo
14 | import com.zero_code.libEdImage.IS_DEBUG
15 | import com.zero_code.libEdImage.startEditImage
16 | import kotlinx.android.synthetic.main.activity_main.*
17 | import kotlinx.coroutines.CoroutineScope
18 | import kotlinx.coroutines.Dispatchers
19 | import kotlinx.coroutines.MainScope
20 | import kotlinx.coroutines.withContext
21 |
22 |
23 | /**
24 | * 测试用的app
25 | * @author ZeroCode
26 | * @date 2021/5/18 : 11:34
27 | */
28 | class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
29 |
30 | private val test =
31 | "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fyouimg1.c-ctrip.com%2Ftarget%2Ftg%2F035%2F063%2F726%2F3ea4031f045945e1843ae5156749d64c.jpg&refer=http%3A%2F%2Fyouimg1.c-ctrip.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1623049590&t=d510aeb8f12616210691111148795c78".trim()
32 |
33 | override fun onCreate(savedInstanceState: Bundle?) {
34 | super.onCreate(savedInstanceState)
35 | setContentView(R.layout.activity_main)
36 | // launch {
37 | // val bitmap = getBitmap()
38 | // image_canvas.setImageBitmap(bitmap)
39 | // image_canvas.mode= IMGMode.MOSAIC
40 | // }
41 |
42 |
43 | }
44 |
45 |
46 | fun selectImage(view: View) {
47 | selectFromAlbum()
48 | }
49 |
50 |
51 | private suspend fun getBitmap(src: String): Bitmap {
52 | return withContext(Dispatchers.IO) {
53 | Glide.with(this@MainActivity)
54 | .asBitmap()
55 | .load(src)
56 | .submit().get()
57 | }
58 | }
59 |
60 | /**
61 | * 从相册选择
62 | */
63 | private fun selectFromAlbum() {
64 | EasyPhotos.createAlbum(
65 | this,
66 | false,
67 | true,
68 | GlideEngine.createGlideEngine()
69 | )//参数说明:上下文,是否显示相机按钮,是否使用宽高数据(false时宽高数据为0,扫描速度更快),[配置Glide为图片加载引擎](https://github.com/HuanTanSheng/EasyPhotos/wiki/12-%E9%85%8D%E7%BD%AEImageEngine%EF%BC%8C%E6%94%AF%E6%8C%81%E6%89%80%E6%9C%89%E5%9B%BE%E7%89%87%E5%8A%A0%E8%BD%BD%E5%BA%93)
70 | .start(12)
71 | }
72 |
73 |
74 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
75 | super.onActivityResult(requestCode, resultCode, data)
76 | if (requestCode == 22 && resultCode == Activity.RESULT_OK) {
77 | //表示返回成功
78 | val filePath = data?.getStringExtra("data")
79 | filePath?.let {
80 | if (IS_DEBUG) Log.e("", it)
81 | Glide.with(this).load(it).into(image)
82 | }
83 |
84 | } else if (requestCode == 12 && resultCode == Activity.RESULT_OK) {
85 |
86 | val resultPhotos: ArrayList =
87 | data?.getParcelableArrayListExtra(EasyPhotos.RESULT_PHOTOS) as ArrayList
88 |
89 |
90 | if (resultPhotos.isNullOrEmpty()) {
91 | return
92 | }
93 | startEditImage(resultPhotos[0].path, 22)
94 |
95 |
96 | // launch {
97 | // val bitmap = getBitmap(selectPic.path)
98 | // image_canvas.setImageBitmap(bitmap)
99 | // image_canvas.mode = IMGMode.NONE
100 | // }
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/drawable/test.jpg
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | EditImage
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app/src/test/java/com/zero_code/editimage/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.editimage
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | ext.kotlin_version = "1.3.72"
4 | repositories {
5 | google()
6 | jcenter()
7 | }
8 | dependencies {
9 | classpath "com.android.tools.build:gradle:4.1.3"
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | // classpath 'com.github.dcendents:android-maven-plugin:1.3'
12 | // classpath 'com.github.dcendents:android-maven-gradle-plugin:1.2'
13 | // classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 |
17 |
18 | classpath "com.github.dcendents:android-maven-gradle-plugin:1.5"
19 | classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0"
20 | }
21 | }
22 |
23 | allprojects {
24 | repositories {
25 | google()
26 | jcenter()
27 | maven { url "https://jitpack.io" }
28 | }
29 | }
30 |
31 | task clean(type: Delete) {
32 | delete rootProject.buildDir
33 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat May 08 10:38:21 CST 2021
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-6.5-bin.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/lib_edImage/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lib_edImage/aar/lib_edImage-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/aar/lib_edImage-release.aar
--------------------------------------------------------------------------------
/lib_edImage/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 | apply plugin: 'maven'
6 | apply plugin:'com.github.dcendents.android-maven'
7 |
8 |
9 | group='com.github.OneZeroYang'
10 |
11 | kapt {
12 | generateStubs = true
13 | }
14 | android {
15 | compileSdkVersion 30
16 |
17 | defaultConfig {
18 | minSdkVersion 16
19 | targetSdkVersion 30
20 | versionCode 1
21 | versionName "1.0"
22 |
23 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
24 |
25 | }
26 |
27 | buildTypes {
28 | release {
29 | minifyEnabled false
30 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
31 | }
32 | }
33 |
34 |
35 | //启用DataBinding
36 | dataBinding {
37 | enabled true
38 | }
39 |
40 | compileOptions {
41 | sourceCompatibility JavaVersion.VERSION_1_8
42 | targetCompatibility JavaVersion.VERSION_1_8
43 | }
44 |
45 | }
46 |
47 | dependencies {
48 | implementation fileTree(include: ['*.jar'], dir: 'libs')
49 | implementation 'androidx.appcompat:appcompat:1.1.0'
50 | implementation 'androidx.core:core-ktx:1.2.0'
51 | // implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
52 | // implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
53 | // implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
54 | implementation 'androidx.recyclerview:recyclerview:1.1.0'
55 | implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
56 | kapt "com.android.databinding:compiler:4.1.2"
57 | }
58 |
59 |
60 | //uploadArchives {
61 | // repositories.mavenDeployer {
62 | // def mavenDirPath = file('D:\\Android Project\\EdtiImageTools')
63 | // repository(url: "file://${mavenDirPath.absolutePath}")
64 | // pom.project {
65 | // groupId "com.github.zeroCode"
66 | // artifactId "EditImage"
67 | // version "1.0.0."
68 | // }
69 | // }
70 | //}
71 |
--------------------------------------------------------------------------------
/lib_edImage/proguard-rules.pro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/ImageConfig.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage
2 |
3 |
4 | /**
5 | * 是否 debug
6 | * 主要用于日志输出
7 | */
8 | const val IS_DEBUG=false
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/adapter/BaseAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.adapter
2 |
3 | import androidx.databinding.DataBindingUtil
4 | import androidx.databinding.ViewDataBinding
5 | import androidx.annotation.LayoutRes
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import androidx.recyclerview.widget.RecyclerView
10 | import java.util.*
11 | import com.zero_code.libEdImage.*
12 |
13 | /**
14 | * 通用Adapter
15 | * Created by Extends on 2017/3/23.
16 | */
17 |
18 | open class BaseAdapter(@LayoutRes layoutId: Int, dataList: ArrayList, isStandard: Boolean = true) : BaseRecyclerAdapter(),
19 | ItemTouchHelperAdapter {
20 | private var layoutId: Int = 0
21 | private var isStandard: Boolean = true
22 | private var if_onBind: OnBind? = null
23 | private var mPresenter: Presenter? = null
24 |
25 | override fun onCreate(parent: ViewGroup?, viewType: Int): Holder {
26 | return Holder(LayoutInflater.from(parent?.context).inflate(layoutId, parent, false))
27 | }
28 |
29 | override fun onBind(viewHolder: Holder, realPosition: Int, data: T) {
30 | if (isStandard) {
31 | (viewHolder.getBinding() as BD).apply {
32 | setVariable(BR.item, data)
33 | setVariable(BR.presenter, getPresenter())
34 | setVariable(BR.position,realPosition)
35 | }
36 | }
37 | if_onBind?.onBind(viewHolder.getBinding() as BD, realPosition, data)
38 | //不加这一行,刷新时会闪烁
39 | //当变量的值更新的时候,binding 对象将在下个更新周期中更新。这样就会有一点时间间隔,
40 | // 如果你像立刻更新,则可以使用 executePendingBindings 函数。
41 | viewHolder.getBinding()?.executePendingBindings()
42 | }
43 |
44 | fun setOnBind(if_onBind: OnBind) {
45 | this.if_onBind = if_onBind
46 | }
47 |
48 | fun onBind(l: (itemBingding: BD, position: Int, data: T) -> Unit) {
49 | setOnBind(object : OnBind {
50 | override fun onBind(itemBingding: BD, position: Int, data: T) {
51 | l(itemBingding, position, data)
52 | }
53 | })
54 | }
55 |
56 | fun setPresenter(presenter: Presenter) {
57 | mPresenter = presenter
58 | }
59 |
60 | protected fun getPresenter(): Presenter? {
61 | return mPresenter
62 | }
63 |
64 | class Holder(view: View) : RecyclerView.ViewHolder(view) {
65 | private val b: ViewDataBinding? by lazy {
66 | DataBindingUtil.bind(itemView)
67 | }
68 |
69 | fun getBinding(): ViewDataBinding? {
70 | return b
71 | }
72 | }
73 |
74 | var onItemMove : ((fromPosition: Int, toPosition: Int)->Unit)? = null
75 |
76 | var onItemDissmiss : ((position: Int)->Unit)? = null
77 |
78 | override fun onItemMove(fromPosition: Int, toPosition: Int) {
79 | Collections.swap(datas,fromPosition,toPosition)
80 | notifyItemMoved(fromPosition,toPosition)
81 | onItemMove?.invoke(fromPosition, toPosition)
82 | }
83 |
84 | override fun onItemDissmiss(position: Int) {
85 | //移除数据
86 | datas.removeAt(position)
87 | notifyItemRemoved(position)
88 | onItemDissmiss?.invoke(position)
89 | }
90 |
91 | init {
92 | this.layoutId = layoutId
93 | this.isStandard = isStandard
94 | datas = dataList
95 | }
96 |
97 | interface OnBind {
98 | fun onBind(itemBingding: BD, position: Int, data: T)
99 | }
100 |
101 | interface Presenter
102 | }
103 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/adapter/adapter.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.adapter
2 |
3 | import androidx.recyclerview.widget.ItemTouchHelper
4 | import androidx.recyclerview.widget.RecyclerView
5 |
6 |
7 | /**
8 | *
9 | * @author Extends
10 | * @date 2018/12/19/019
11 | */
12 | interface ItemTouchHelperAdapter{
13 | //数据交换
14 | fun onItemMove(fromPosition:Int,toPosition:Int)
15 | //数据删除
16 | fun onItemDissmiss(position:Int)
17 | }
18 |
19 | class SimpleItemTouchHelperCallback(val mAdapter: ItemTouchHelperAdapter): ItemTouchHelper.Callback(){
20 |
21 | /**
22 | * 该方法用于返回可以滑动的方向
23 | */
24 | override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
25 | //允许上下的拖动
26 | val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
27 | //只允许从右向左侧滑
28 | val swipeFlags = ItemTouchHelper.LEFT
29 | return makeMovementFlags(dragFlags,swipeFlags)
30 | }
31 |
32 | /**
33 | * 该方法返回true时,表示支持长按拖动
34 | */
35 | override fun isLongPressDragEnabled() = true
36 |
37 | /**
38 | * 该方法返回true时,表示如果用户触摸并左右滑动了View,那么可以执行滑动删除操作
39 | */
40 | override fun isItemViewSwipeEnabled() = true
41 |
42 | /**
43 | * 当用户拖动一个Item进行上下移动从旧的位置到新的位置的时候会调用该方法,
44 | * 在该方法内,我们可以调用Adapter的notifyItemMoved方法来交换两个ViewHolder的位置,
45 | * 最后返回true,表示被拖动的ViewHolder已经移动到了目的位置。
46 | * 所以,如果要实现拖动交换位置,可以重写该方法
47 | */
48 | override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
49 | mAdapter.onItemMove(viewHolder.adapterPosition,target.adapterPosition)
50 | return true
51 | }
52 |
53 | /**
54 | * 当用户左右滑动Item达到删除条件时,会调用该方法,一般手指触摸滑动的距离达到RecyclerView宽度的一半时,
55 | * 再松开手指,此时该Item会继续向原先滑动方向滑过去并且调用onSwiped方法进行删除,否则会反向滑回原来的位置
56 | */
57 | override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
58 | mAdapter.onItemDissmiss(viewHolder.adapterPosition)
59 | }
60 | }
61 |
62 | class DragItemTouchHelperCallback(val mAdapter: ItemTouchHelperAdapter): ItemTouchHelper.Callback(){
63 | override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
64 | val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
65 | return makeMovementFlags(dragFlags,0)
66 | }
67 |
68 | override fun isLongPressDragEnabled() = true
69 | override fun isItemViewSwipeEnabled() = false
70 | override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
71 | mAdapter.onItemMove(viewHolder.adapterPosition,target.adapterPosition)
72 | return true
73 | }
74 | override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
75 |
76 | var onDragEnd : (()->Unit)?=null
77 | override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
78 | super.onSelectedChanged(viewHolder, actionState)
79 | when(actionState){
80 | ItemTouchHelper.ACTION_STATE_SWIPE -> {
81 | //开始删除
82 | }
83 | ItemTouchHelper.ACTION_STATE_DRAG -> {
84 | //开始拖动
85 | }
86 | ItemTouchHelper.ACTION_STATE_IDLE -> {
87 | //结束拖动或删除
88 | onDragEnd?.invoke()
89 | }
90 | else -> {}
91 | }
92 | }
93 | }
94 |
95 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/adapter/animation.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.adapter
2 |
3 | import android.animation.Animator
4 | import android.animation.ObjectAnimator
5 | import android.view.View
6 |
7 | /**
8 | * Created by Extends on 2018/4/14/014.
9 | */
10 | interface BaseAnimation {
11 | fun getAnimators(view: View): Array
12 | }
13 |
14 | /**
15 | * 透明度动画
16 | */
17 | class AlphaInAnimation @JvmOverloads constructor(private val mFrom: Float = DEFAULT_ALPHA_FROM) :
18 | BaseAnimation {
19 | override fun getAnimators(view: View): Array {
20 | return arrayOf(ObjectAnimator.ofFloat(view, "alpha", mFrom, 1f))
21 | }
22 | companion object {
23 | private val DEFAULT_ALPHA_FROM = 0f
24 | }
25 | }
26 |
27 | /**
28 | * 缩放动画
29 | */
30 | class ScaleInAnimation @JvmOverloads constructor(private val mFrom: Float = DEFAULT_SCALE_FROM) :
31 | BaseAnimation {
32 | override fun getAnimators(view: View): Array {
33 | val scaleX = ObjectAnimator.ofFloat(view, "scaleX", mFrom, 1f)
34 | val scaleY = ObjectAnimator.ofFloat(view, "scaleY", mFrom, 1f)
35 | return arrayOf(scaleX, scaleY)
36 | }
37 | companion object {
38 | private val DEFAULT_SCALE_FROM = .5f
39 | }
40 | }
41 |
42 | /**
43 | * 从下往上的滑入动画
44 | */
45 | class SlideInBottomAnimation : BaseAnimation {
46 | override fun getAnimators(view: View): Array {
47 | return arrayOf(ObjectAnimator.ofFloat(view, "translationY", view.measuredHeight.toFloat(), 0f))
48 | }
49 | }
50 |
51 | /**
52 | * 从上往下的滑入动画
53 | */
54 | class SlideInTopAnimation : BaseAnimation {
55 | override fun getAnimators(view: View): Array {
56 | return arrayOf(ObjectAnimator.ofFloat(view, "translationY", -view.measuredHeight.toFloat(), 0f))
57 | }
58 | }
59 |
60 | /**
61 | * 从左往右的滑入动画
62 | */
63 | class SlideInLeftAnimation : BaseAnimation {
64 | override fun getAnimators(view: View): Array {
65 | return arrayOf(ObjectAnimator.ofFloat(view, "translationX", -view.rootView.width.toFloat(), 0f))
66 | }
67 | }
68 |
69 | /**
70 | * 从右往左的滑入动画
71 | */
72 | class SlideInRightAnimation : BaseAnimation {
73 | override fun getAnimators(view: View): Array {
74 | return arrayOf(ObjectAnimator.ofFloat(view, "translationX", view.rootView.width.toFloat(), 0f))
75 | }
76 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/anim/EditHomingAnimator.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.anim;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.view.animation.AccelerateDecelerateInterpolator;
5 |
6 | import com.zero_code.libEdImage.homing.EditHoming;
7 | import com.zero_code.libEdImage.homing.EditHomingEvaluator;
8 |
9 | /**
10 | *
11 | * @author ZeroCode
12 | * @date 2021/5/17 : 14:16
13 | */
14 |
15 | public class EditHomingAnimator extends ValueAnimator {
16 |
17 | private boolean isRotate = false;
18 |
19 | private EditHomingEvaluator mEvaluator;
20 |
21 | public EditHomingAnimator() {
22 | setInterpolator(new AccelerateDecelerateInterpolator());
23 | }
24 |
25 | @Override
26 | public void setObjectValues(Object... values) {
27 | super.setObjectValues(values);
28 | if (mEvaluator == null) {
29 | mEvaluator = new EditHomingEvaluator();
30 |
31 | }
32 | setEvaluator(mEvaluator);
33 | }
34 |
35 | public void setHomingValues(EditHoming sHoming, EditHoming eHoming) {
36 | setObjectValues(sHoming, eHoming);
37 | isRotate = EditHoming.isRotate(sHoming, eHoming);
38 | }
39 |
40 | public boolean isRotate() {
41 | return isRotate;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/clip/EditClip.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.clip;
2 |
3 | import android.graphics.RectF;
4 |
5 | /**
6 | *
7 | * @author ZeroCode
8 | * @date 2021/5/17 : 14:16
9 | */
10 |
11 | public interface EditClip {
12 |
13 | /**
14 | * 裁剪区域的边距
15 | */
16 | float CLIP_MARGIN = 60f;
17 |
18 | /**
19 | * 角尺寸
20 | */
21 | float CLIP_CORNER_SIZE = 48f;
22 |
23 | /**
24 | * 裁剪区域最小尺寸
25 | */
26 | float CLIP_FRAME_MIN = CLIP_CORNER_SIZE * 3.14f;
27 |
28 | /**
29 | * 内边厚度
30 | */
31 | float CLIP_THICKNESS_CELL = 3f;
32 |
33 | /**
34 | * 外边框厚度
35 | */
36 | float CLIP_THICKNESS_FRAME = 8f;
37 |
38 | /**
39 | * 角边厚度
40 | */
41 | float CLIP_THICKNESS_SEWING = 14f;
42 |
43 | /**
44 | * 比例尺,用于计算出 {0, width, 1/3 width, 2/3 width} & {0, height, 1/3 height, 2/3 height}
45 | */
46 | float[] CLIP_SIZE_RATIO = {0, 1, 0.33f, 0.66f};
47 |
48 | int CLIP_CELL_STRIDES = 0x7362DC98;
49 |
50 | int CLIP_CORNER_STRIDES = 0x0AAFF550;
51 |
52 | float[] CLIP_CORNER_STEPS = {0, 3, -3};
53 |
54 | float[] CLIP_CORNER_SIZES = {0, CLIP_CORNER_SIZE, -CLIP_CORNER_SIZE};
55 |
56 | byte[] CLIP_CORNERS = {
57 | 0x8, 0x8, 0x9, 0x8,
58 | 0x6, 0x8, 0x4, 0x8,
59 | 0x4, 0x8, 0x4, 0x1,
60 | 0x4, 0xA, 0x4, 0x8,
61 | 0x4, 0x4, 0x6, 0x4,
62 | 0x9, 0x4, 0x8, 0x4,
63 | 0x8, 0x4, 0x8, 0x6,
64 | 0x8, 0x9, 0x8, 0x8
65 | };
66 |
67 | enum Anchor {
68 | LEFT(1),
69 | RIGHT(2),
70 | TOP(4),
71 | BOTTOM(8),
72 | LEFT_TOP(5),
73 | RIGHT_TOP(6),
74 | LEFT_BOTTOM(9),
75 | RIGHT_BOTTOM(10);
76 |
77 | int v;
78 |
79 | /**
80 | * LEFT: 0
81 | * TOP: 2
82 | * RIGHT: 1
83 | * BOTTOM: 3
84 | */
85 |
86 | final static int P = 0, N = 1;
87 |
88 | final static int H = 0, V = 2;
89 |
90 | final static int[] PN = {1, -1};
91 |
92 | Anchor(int v) {
93 | this.v = v;
94 | }
95 |
96 | public void move(RectF win, RectF frame, float dx, float dy) {
97 | float[] maxFrame = cohesion(win, CLIP_MARGIN);
98 | float[] minFrame = cohesion(frame, CLIP_FRAME_MIN);
99 | float[] theFrame = cohesion(frame, 0);
100 |
101 | float[] dxy = {dx, 0, dy};
102 | for (int i = 0; i < 4; i++) {
103 | if (((1 << i) & v) != 0) {
104 |
105 | int pn = PN[i & 1];
106 |
107 | theFrame[i] = pn * revise(pn * (theFrame[i] + dxy[i & 2]),
108 | pn * maxFrame[i], pn * minFrame[i + PN[i & 1]]);
109 | }
110 | }
111 |
112 | frame.set(theFrame[0], theFrame[2], theFrame[1], theFrame[3]);
113 | }
114 |
115 | public static float revise(float v, float min, float max) {
116 | return Math.min(Math.max(v, min), max);
117 | }
118 |
119 | public static float[] cohesion(RectF win, float v) {
120 | return new float[]{
121 | win.left + v, win.right - v,
122 | win.top + v, win.bottom - v
123 | };
124 | }
125 |
126 | public static boolean isCohesionContains(RectF frame, float v, float x, float y) {
127 | return frame.left + v < x && frame.right - v > x
128 | && frame.top + v < y && frame.bottom - v > y;
129 | }
130 |
131 | public static Anchor valueOf(int v) {
132 | Anchor[] values = values();
133 | for (Anchor anchor : values) {
134 | if (anchor.v == v) {
135 | return anchor;
136 | }
137 | }
138 | return null;
139 | }
140 | }
141 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/clip/EditClipWindow.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.clip;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Color;
5 | import android.graphics.Matrix;
6 | import android.graphics.Paint;
7 | import android.graphics.Path;
8 | import android.graphics.RectF;
9 |
10 | import com.zero_code.libEdImage.util.IMGUtils;
11 |
12 | /**
13 | * 剪裁的View
14 | *
15 | * @author ZeroCode
16 | * @date 2021/5/8 : 13:33
17 | */
18 | public class EditClipWindow implements EditClip {
19 |
20 | /**
21 | * 裁剪区域
22 | */
23 | private RectF mFrame = new RectF();
24 |
25 | private RectF mBaseFrame = new RectF();
26 |
27 | private RectF mTargetFrame = new RectF();
28 |
29 | /**
30 | * 裁剪窗口
31 | */
32 | private RectF mWinFrame = new RectF();
33 |
34 | private RectF mWin = new RectF();
35 |
36 | private float[] mCells = new float[16];
37 |
38 | private float[] mCorners = new float[32];
39 |
40 | private float[][] mBaseSizes = new float[2][4];
41 |
42 | /**
43 | * 是否在裁剪中
44 | */
45 | private boolean isClipping = false;
46 |
47 | private boolean isResetting = true;
48 |
49 | private boolean isShowShade = false;
50 |
51 | private boolean isHoming = false;
52 |
53 | private Matrix M = new Matrix();
54 |
55 | private Path mShadePath = new Path();
56 |
57 | private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
58 |
59 | /**
60 | * 垂直窗口比例
61 | */
62 | private static final float VERTICAL_RATIO = 0.8f;
63 |
64 | private static final int COLOR_CELL = 0x80FFFFFF;
65 |
66 | private static final int COLOR_FRAME = Color.parseColor("#007EFA"); //边框的颜色
67 |
68 | private static final int COLOR_CORNER = Color.parseColor("#007EFA"); //边框4角的颜色
69 |
70 | private static final int COLOR_SHADE = 0xCC000000;
71 |
72 | {
73 | mPaint.setStyle(Paint.Style.STROKE);
74 | mPaint.setStrokeCap(Paint.Cap.SQUARE);
75 | }
76 |
77 | public EditClipWindow() {
78 |
79 | }
80 |
81 | /**
82 | * 计算裁剪窗口区域
83 | */
84 | public void setClipWinSize(float width, float height) {
85 | mWin.set(0, 0, width, height);
86 | mWinFrame.set(0, 0, width, height * VERTICAL_RATIO);
87 |
88 | if (!mFrame.isEmpty()) {
89 | IMGUtils.center(mWinFrame, mFrame);
90 | mTargetFrame.set(mFrame);
91 | }
92 | }
93 |
94 | public void reset(RectF clipImage, float rotate) {
95 | RectF imgRect = new RectF();
96 | M.setRotate(rotate, clipImage.centerX() , clipImage.centerY());
97 | M.mapRect(imgRect, clipImage);
98 | reset(imgRect.width(), imgRect.height());
99 | }
100 |
101 | /**
102 | * 重置裁剪
103 | */
104 | private void reset(float clipWidth, float clipHeight) {
105 | setResetting(true);
106 | mFrame.set(0, 0, clipWidth, clipHeight);
107 | IMGUtils.fitCenter(mWinFrame, mFrame, CLIP_MARGIN);
108 | mTargetFrame.set(mFrame);
109 | }
110 |
111 |
112 |
113 | public boolean homing() {
114 | mBaseFrame.set(mFrame);
115 | mTargetFrame.set(mFrame);
116 | IMGUtils.fitCenter(mWinFrame, mTargetFrame, CLIP_MARGIN);
117 | return isHoming = !mTargetFrame.equals(mBaseFrame);
118 | }
119 |
120 | public void homing(float fraction) {
121 | if (isHoming) {
122 | mFrame.set(
123 | mBaseFrame.left + (mTargetFrame.left - mBaseFrame.left) * fraction,
124 | mBaseFrame.top + (mTargetFrame.top - mBaseFrame.top) * fraction,
125 | mBaseFrame.right + (mTargetFrame.right - mBaseFrame.right) * fraction,
126 | mBaseFrame.bottom + (mTargetFrame.bottom - mBaseFrame.bottom) * fraction
127 | );
128 | }
129 | }
130 |
131 | public boolean isHoming() {
132 | return isHoming;
133 | }
134 |
135 | public void setHoming(boolean homing) {
136 | isHoming = homing;
137 | }
138 |
139 | public boolean isClipping() {
140 | return isClipping;
141 | }
142 |
143 | public void setClipping(boolean clipping) {
144 | isClipping = clipping;
145 | }
146 |
147 | public boolean isResetting() {
148 | return isResetting;
149 | }
150 |
151 | public void setResetting(boolean resetting) {
152 | isResetting = resetting;
153 | }
154 |
155 | public RectF getFrame() {
156 | return mFrame;
157 | }
158 |
159 | public RectF getWinFrame() {
160 | return mWinFrame;
161 | }
162 |
163 | public RectF getOffsetFrame(float offsetX, float offsetY) {
164 | RectF frame = new RectF(mFrame);
165 | frame.offset(offsetX, offsetY);
166 | return frame;
167 | }
168 |
169 | public RectF getTargetFrame() {
170 | return mTargetFrame;
171 | }
172 |
173 | public RectF getOffsetTargetFrame(float offsetX, float offsetY) {
174 | RectF targetFrame = new RectF(mFrame);
175 | targetFrame.offset(offsetX, offsetY);
176 | return targetFrame;
177 | }
178 |
179 | public boolean isShowShade() {
180 | return isShowShade;
181 | }
182 |
183 | public void setShowShade(boolean showShade) {
184 | isShowShade = showShade;
185 | }
186 |
187 | public void onDraw(Canvas canvas) {
188 |
189 | if (isResetting) {
190 | return;
191 | }
192 |
193 |
194 |
195 | float[] size = {mFrame.width(), mFrame.height()};
196 | for (int i = 0; i < mBaseSizes.length; i++) {
197 | for (int j = 0; j < mBaseSizes[i].length; j++) {
198 | mBaseSizes[i][j] = size[i] * CLIP_SIZE_RATIO[j];
199 | }
200 | }
201 |
202 | for (int i = 0; i < mCells.length; i++) {
203 | mCells[i] = mBaseSizes[i & 1][CLIP_CELL_STRIDES >>> (i << 1) & 3];
204 | }
205 |
206 | for (int i = 0; i < mCorners.length; i++) {
207 | mCorners[i] = mBaseSizes[i & 1][CLIP_CORNER_STRIDES >>> i & 1]
208 | + CLIP_CORNER_SIZES[CLIP_CORNERS[i] & 3] + CLIP_CORNER_STEPS[CLIP_CORNERS[i] >> 2];
209 | }
210 |
211 | canvas.translate(mFrame.left, mFrame.top);
212 | mPaint.setStyle(Paint.Style.STROKE);
213 | mPaint.setColor(COLOR_CELL);
214 | mPaint.setStrokeWidth(CLIP_THICKNESS_CELL);
215 | canvas.drawLines(mCells, mPaint);
216 |
217 | canvas.translate(-mFrame.left, -mFrame.top);
218 | mPaint.setColor(COLOR_FRAME);
219 | mPaint.setStrokeWidth(CLIP_THICKNESS_FRAME);
220 | canvas.drawRect(mFrame, mPaint);
221 |
222 | canvas.translate(mFrame.left, mFrame.top);
223 | mPaint.setColor(COLOR_CORNER);
224 | mPaint.setStrokeWidth(CLIP_THICKNESS_SEWING);
225 | canvas.drawLines(mCorners, mPaint);
226 | }
227 |
228 | // public void onDrawShade(Canvas canvas) {
229 | // if (!isShowShade) return;
230 | //
231 | // // 计算遮罩图形
232 | // mShadePath.reset();
233 | //
234 | // mShadePath.setFillType(Path.FillType.WINDING);
235 | // mShadePath.addRect(mFrame.left + 100, mFrame.top + 100, mFrame.right - 100, mFrame.bottom - 100, Path.Direction.CW);
236 | //
237 | // mPaint.setColor(COLOR_SHADE);
238 | // mPaint.setStyle(Paint.Style.FILL);
239 | // canvas.drawPath(mShadePath, mPaint);
240 | // }
241 |
242 | public Anchor getAnchor(float x, float y) {
243 | if (Anchor.isCohesionContains(mFrame, -CLIP_CORNER_SIZE, x, y)
244 | && !Anchor.isCohesionContains(mFrame, CLIP_CORNER_SIZE, x, y)) {
245 | int v = 0;
246 | float[] cohesion = Anchor.cohesion(mFrame, 0);
247 | float[] pos = {x, y};
248 | for (int i = 0; i < cohesion.length; i++) {
249 | if (Math.abs(cohesion[i] - pos[i >> 1]) < CLIP_CORNER_SIZE) {
250 | v |= 1 << i;
251 | }
252 | }
253 |
254 | Anchor anchor = Anchor.valueOf(v);
255 | if (anchor != null) {
256 | isHoming = false;
257 | }
258 | return anchor;
259 | }
260 | return null;
261 | }
262 |
263 | public void onScroll(Anchor anchor, float dx, float dy) {
264 | anchor.move(mWinFrame, mFrame, dx, dy);
265 | }
266 |
267 |
268 | }
269 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/clip/EditImageViewPortrait.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.clip
2 |
3 | /**
4 | * IMGViewPortrait
5 | * @author ZeroCode
6 | * @date 2021/5/8 : 13:35
7 | */
8 | interface EditImageViewPortrait {
9 | val width: Int
10 | val height: Int
11 | var scaleX: Float
12 | var scaleY: Float
13 | var rotation: Float
14 | val pivotX: Float
15 | val pivotY: Float
16 | var x: Float
17 | var y: Float
18 | var scale: Float
19 | fun addScale(scale: Float)
20 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/core/EditImageArrows.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.core
2 |
3 | import android.graphics.Path
4 | import com.zero_code.libEdImage.view.ArrowsCoordinate
5 | import com.zero_code.libEdImage.view.PathArrows
6 |
7 | /**
8 | * 箭头封装类
9 | * @author ZeroCode
10 | * @date 2021/5/17 : 9:48
11 | */
12 | object EditImageArrows {
13 | var pathList: ArrayList = arrayListOf()
14 |
15 | var path: Path = Path()
16 |
17 |
18 | fun addArrows(x: Float, y: Float, color: Int, size: Int) {
19 | pathList.add(
20 | PathArrows(
21 | ArrowsCoordinate(x, y),
22 | ArrowsCoordinate(x, y),
23 | color,
24 | size
25 | )
26 | )
27 | }
28 |
29 | fun upDateArrows(x: Float, y: Float) {
30 | val orNull = pathList.getOrNull(
31 | pathList.size - 1)
32 | if (orNull != null) {
33 | orNull.end = ArrowsCoordinate(x, y)
34 | }
35 | }
36 |
37 | fun deleteArrows() {
38 | if (!pathList.isNullOrEmpty() && pathList.size > 0) {
39 | pathList.removeAt(
40 | pathList.size - 1)
41 | }
42 | }
43 |
44 | fun init() {
45 | pathList = arrayListOf()
46 | path = Path()
47 | }
48 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/core/EditImageMode.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.core
2 |
3 | /**
4 | * 操作类型
5 | * @author ZeroCode
6 | * @date 2021/5/8 : 13:35
7 | */
8 | enum class EditImageMode {
9 | NONE, DOODLE, //涂鸦
10 | MOSAIC, //马赛克
11 | CLIP, //剪裁
12 | ARROWS //箭头
13 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/core/EditImagePath.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.core
2 |
3 | import android.graphics.*
4 |
5 | /**
6 | * IMGPath
7 | * @author ZeroCode
8 | * @date 2021/5/8 : 13:35
9 | */
10 | open class EditImagePath @JvmOverloads constructor(
11 | var path: Path = Path(),
12 | mode: EditImageMode = EditImageMode.DOODLE,
13 | color: Int = Color.RED,
14 | // 初始化是,这里会导致马赛克的 宽带固定死 ,应该写活哈
15 | width: Float = BASE_MOSAIC_WIDTH
16 | ) {
17 | var color = Color.RED
18 | var width =
19 | BASE_MOSAIC_WIDTH
20 | var mode = EditImageMode.DOODLE
21 |
22 | fun onDrawDoodle(canvas: Canvas, paint: Paint) {
23 | if (mode == EditImageMode.DOODLE) {
24 | paint.color = color
25 | paint.strokeWidth =
26 | BASE_DOODLE_WIDTH
27 | // rewind
28 | canvas.drawPath(path, paint)
29 | }
30 | }
31 |
32 | fun onDrawMosaic(canvas: Canvas, paint: Paint) {
33 | if (mode == EditImageMode.MOSAIC) {
34 | paint.strokeWidth = width
35 | canvas.drawPath(path, paint)
36 | }
37 | }
38 |
39 | fun transform(matrix: Matrix?) {
40 | path.transform(matrix!!)
41 | }
42 |
43 | companion object {
44 | const val BASE_DOODLE_WIDTH = 20f
45 | var BASE_MOSAIC_WIDTH = 72f
46 | }
47 |
48 | init {
49 | this.mode = mode
50 | this.color = color
51 | this.width = width
52 | if (mode == EditImageMode.MOSAIC) {
53 | path.fillType = Path.FillType.EVEN_ODD
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/elastic/EditElastic.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.elastic;
2 |
3 | import android.graphics.PointF;
4 |
5 | /**
6 | *
7 | * @author ZeroCode
8 | * @date 2021/5/17 : 14:16
9 | */
10 |
11 | public class EditElastic {
12 |
13 | private float width, height;
14 |
15 | private PointF pivot = new PointF();
16 |
17 | public EditElastic() {
18 |
19 | }
20 |
21 | public EditElastic(float x, float y) {
22 | pivot.set(x, y);
23 | }
24 |
25 | public EditElastic(float x, float y, float width, float height) {
26 | pivot.set(x, y);
27 | this.width = width;
28 | this.height = height;
29 | }
30 |
31 | public float getWidth() {
32 | return width;
33 | }
34 |
35 | public void setWidth(float width) {
36 | this.width = width;
37 | }
38 |
39 | public float getHeight() {
40 | return height;
41 | }
42 |
43 | public void setHeight(float height) {
44 | this.height = height;
45 | }
46 |
47 | public float getX() {
48 | return pivot.x;
49 | }
50 |
51 | public void setX(float x) {
52 | pivot.x = x;
53 | }
54 |
55 | public float getY() {
56 | return pivot.y;
57 | }
58 |
59 | public void setY(float y) {
60 | pivot.y = y;
61 | }
62 |
63 | public void setXY(float x, float y) {
64 | pivot.set(x, y);
65 | }
66 |
67 | public PointF getPivot() {
68 | return pivot;
69 | }
70 |
71 | public void setSize(float width, float height) {
72 | this.width = width;
73 | this.height = height;
74 | }
75 |
76 | public void set(float x, float y, float width, float height) {
77 | pivot.set(x, y);
78 | this.width = width;
79 | this.height = height;
80 | }
81 |
82 | @Override
83 | public String toString() {
84 | return "IMGElastic{" +
85 | "width=" + width +
86 | ", height=" + height +
87 | ", pivot=" + pivot +
88 | '}';
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/elastic/EditElasticAnimator.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.elastic
2 |
3 | import android.animation.ValueAnimator
4 | import android.graphics.PointF
5 | import android.view.animation.AccelerateDecelerateInterpolator
6 |
7 | /**
8 | * IMGElasticAnimator
9 | * @author ZeroCode
10 | * @date 2021/5/8 : 13:38
11 | */
12 | class EditElasticAnimator() : ValueAnimator() {
13 | private var mElastic: EditElastic? = null
14 |
15 | constructor(elastic: EditElastic?) : this() {
16 | setElastic(elastic)
17 | }
18 |
19 | fun setElastic(elastic: EditElastic?) {
20 | mElastic = elastic
21 | requireNotNull(mElastic) { "IMGElastic cannot be null." }
22 | }
23 |
24 | fun start(x: Float, y: Float) {
25 | setObjectValues(PointF(x, y), mElastic!!.pivot)
26 | start()
27 | }
28 |
29 | init {
30 | setEvaluator(EditPointFEvaluator())
31 | interpolator = AccelerateDecelerateInterpolator()
32 | }
33 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/elastic/EditPointFEvaluator.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.elastic
2 |
3 | import android.animation.TypeEvaluator
4 | import android.graphics.PointF
5 |
6 | /**
7 | * IMGPointFEvaluator
8 | * @author ZeroCode
9 | * @date 2021/5/8 : 13:37
10 | */
11 | class EditPointFEvaluator : TypeEvaluator {
12 | private var mPoint: PointF? = null
13 |
14 | constructor() {}
15 | constructor(reuse: PointF?) {
16 | mPoint = reuse
17 | }
18 |
19 | override fun evaluate(
20 | fraction: Float,
21 | startValue: PointF,
22 | endValue: PointF
23 | ): PointF {
24 | val x = startValue.x + fraction * (endValue.x - startValue.x)
25 | val y = startValue.y + fraction * (endValue.y - startValue.y)
26 | return if (mPoint != null) {
27 | mPoint!![x] = y
28 | mPoint!!
29 | } else {
30 | PointF(x, y)
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/elastic/EditRectFEvaluator.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.elastic
2 |
3 | import android.animation.TypeEvaluator
4 | import android.graphics.RectF
5 |
6 | /**
7 | * IMGRectFEvaluator
8 | * @author ZeroCode
9 | * @date 2021/5/8 : 13:37
10 | */
11 | class EditRectFEvaluator : TypeEvaluator {
12 | private var mRect: RectF? = null
13 |
14 | constructor() {}
15 | constructor(reuseRect: RectF?) {
16 | mRect = reuseRect
17 | }
18 |
19 | override fun evaluate(
20 | fraction: Float,
21 | startValue: RectF,
22 | endValue: RectF
23 | ): RectF {
24 | val left = startValue.left + (endValue.left - startValue.left) * fraction
25 | val top = startValue.top + (endValue.top - startValue.top) * fraction
26 | val right = startValue.right + (endValue.right - startValue.right) * fraction
27 | val bottom =
28 | startValue.bottom + (endValue.bottom - startValue.bottom) * fraction
29 | return if (mRect == null) {
30 | RectF(left, top, right, bottom)
31 | } else {
32 | mRect!![left, top, right] = bottom
33 | mRect!!
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/homing/EditHoming.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.homing;
2 |
3 | /**
4 | *
5 | * @author ZeroCode
6 | * @date 2021/5/17 : 14:16
7 | */
8 |
9 | public class EditHoming {
10 |
11 | public float x, y;
12 |
13 | public float scale;
14 |
15 | public float rotate;
16 |
17 | public EditHoming(float x, float y, float scale, float rotate) {
18 | this.x = x;
19 | this.y = y;
20 | this.scale = scale;
21 | this.rotate = rotate;
22 | }
23 |
24 | public void set(float x, float y, float scale, float rotate) {
25 | this.x = x;
26 | this.y = y;
27 | this.scale = scale;
28 | this.rotate = rotate;
29 | }
30 |
31 | public void concat(EditHoming homing) {
32 | this.scale *= homing.scale;
33 | this.x += homing.x;
34 | this.y += homing.y;
35 | }
36 |
37 | public void rConcat(EditHoming homing) {
38 | this.scale *= homing.scale;
39 | this.x -= homing.x;
40 | this.y -= homing.y;
41 | }
42 |
43 | public static boolean isRotate(EditHoming sHoming, EditHoming eHoming) {
44 | return Float.compare(sHoming.rotate, eHoming.rotate) != 0;
45 | }
46 |
47 | @Override
48 | public String toString() {
49 | return "IMGHoming{" +
50 | "x=" + x +
51 | ", y=" + y +
52 | ", scale=" + scale +
53 | ", rotate=" + rotate +
54 | '}';
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/homing/EditHomingEvaluator.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.homing;
2 |
3 | import android.animation.TypeEvaluator;
4 |
5 | /**
6 | *
7 | * @author ZeroCode
8 | * @date 2021/5/17 : 14:16
9 | */
10 |
11 | public class EditHomingEvaluator implements TypeEvaluator {
12 |
13 | private EditHoming homing;
14 |
15 | public EditHomingEvaluator() {
16 |
17 | }
18 |
19 | public EditHomingEvaluator(EditHoming homing) {
20 | this.homing = homing;
21 | }
22 |
23 | @Override
24 | public EditHoming evaluate(float fraction, EditHoming startValue, EditHoming endValue) {
25 | float x = startValue.x + fraction * (endValue.x - startValue.x);
26 | float y = startValue.y + fraction * (endValue.y - startValue.y);
27 | float scale = startValue.scale + fraction * (endValue.scale - startValue.scale);
28 | float rotate = startValue.rotate + fraction * (endValue.rotate - startValue.rotate);
29 |
30 | if (homing == null) {
31 | homing = new EditHoming(x, y, scale, rotate);
32 | } else {
33 | homing.set(x, y, scale, rotate);
34 | }
35 |
36 | return homing;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/model/ClipViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.model
2 |
3 | import android.view.View
4 | import androidx.lifecycle.Lifecycle
5 | import androidx.lifecycle.LifecycleObserver
6 | import androidx.lifecycle.OnLifecycleEvent
7 | import com.zero_code.libEdImage.EditImageView
8 | import com.zero_code.libEdImage.databinding.ActivityEditImageBinding
9 |
10 | /**
11 | * 剪裁得ViewModel
12 | * @author ZeroCode
13 | * @date 2021/5/13 : 10:21
14 | */
15 | class ClipViewModel(
16 | lifecycle: Lifecycle,
17 | var image: EditImageView?,
18 | var binding: ActivityEditImageBinding?
19 | ) : LifecycleObserver {
20 |
21 | private var rotate=0f
22 | private var isVerticalMirror=false
23 | private var isHorizontalMirror=false
24 |
25 |
26 | init {
27 | lifecycle.addObserver(this)
28 | }
29 |
30 |
31 | @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
32 | fun onDestroy() {
33 | image = null
34 | binding = null
35 | }
36 |
37 |
38 | /**
39 | * left 旋转
40 | */
41 | fun rotateLeft(view: View) {
42 | rotate+=-90
43 | image?.doRotate(-90f)
44 | }
45 |
46 | /**
47 | * Right 旋转
48 | */
49 | fun rotateRight(view: View) {
50 | rotate+=90
51 | image?.doRotate(90f)
52 | }
53 |
54 | /**
55 | * 向上镜面反转
56 | */
57 | fun mirrorUp(view: View) {
58 | image?.doVerticalMirror()
59 | isVerticalMirror=!isVerticalMirror
60 | }
61 |
62 |
63 | /**
64 | * 向左镜像反转
65 | */
66 | fun mirrorLeft(view: View) {
67 | image?.doHorizontalMirror()
68 | isHorizontalMirror=!isHorizontalMirror
69 | }
70 |
71 | /**
72 | * 关闭
73 | */
74 | fun close(view: View) {
75 | binding?.edTools?.visibility = View.VISIBLE
76 | binding?.clipView?.visibility = View.GONE
77 | image?.cancelClip()
78 | }
79 |
80 | /**
81 | * 重置
82 | * TODO 在多次进行旋转 翻转后,重置有一定几率不能恢复至初始状态
83 | */
84 | fun restore(view: View) {
85 | if (isHorizontalMirror) image?.doHorizontalMirror()
86 | if (isVerticalMirror) image?.doVerticalMirror()
87 | isHorizontalMirror=false
88 | isVerticalMirror=false
89 | image?.doRotate(-rotate)
90 | rotate=0f
91 | image?.resetClip()
92 | }
93 |
94 | /**
95 | * 确认
96 | */
97 | fun ok(view: View) {
98 | binding?.edTools?.visibility = View.VISIBLE
99 | binding?.clipView?.visibility = View.GONE
100 | isHorizontalMirror=false
101 | isVerticalMirror=false
102 | rotate=0f
103 | image?.doClip()
104 | }
105 |
106 |
107 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/sticker/EditSticker.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.sticker
2 |
3 | import com.zero_code.libEdImage.clip.EditImageViewPortrait
4 |
5 | /**
6 | *
7 | * @author ZeroCode
8 | * @date 2021/5/8 : 13:33
9 | */
10 | interface EditSticker : EditStickerPortrait,
11 | EditImageViewPortrait
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/sticker/EditStickerHelper.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.sticker;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Matrix;
5 | import android.graphics.RectF;
6 | import android.view.View;
7 |
8 | /**
9 | *
10 | * @author ZeroCode
11 | * @date 2021/5/17 : 14:16
12 | */
13 |
14 | public class EditStickerHelper implements
15 | EditStickerPortrait, EditStickerPortrait.Callback {
16 |
17 | private RectF mFrame;
18 |
19 | private StickerView mView;
20 |
21 | private Callback mCallback;
22 |
23 | private boolean isShowing = false;
24 |
25 | public EditStickerHelper(StickerView view) {
26 | mView = view;
27 | }
28 |
29 | @Override
30 | public boolean show() {
31 | if (!isShowing()) {
32 | isShowing = true;
33 | onShowing(mView);
34 | return true;
35 | }
36 | return false;
37 | }
38 |
39 | @Override
40 | public boolean remove() {
41 | return onRemove(mView);
42 | }
43 |
44 | @Override
45 | public boolean dismiss() {
46 | if (isShowing()) {
47 | isShowing = false;
48 | onDismiss(mView);
49 | return true;
50 | }
51 | return false;
52 | }
53 |
54 | @Override
55 | public boolean isShowing() {
56 | return isShowing;
57 | }
58 |
59 | @Override
60 | public RectF getFrame() {
61 | if (mFrame == null) {
62 | mFrame = new RectF(0, 0, mView.getWidth(), mView.getHeight());
63 | float pivotX = mView.getX() + mView.getPivotX();
64 | float pivotY = mView.getY() + mView.getPivotY();
65 |
66 | Matrix matrix = new Matrix();
67 | matrix.setTranslate(mView.getX(), mView.getY());
68 | matrix.postScale(mView.getScaleX(), mView.getScaleY(), pivotX, pivotY);
69 | matrix.mapRect(mFrame);
70 | }
71 | return mFrame;
72 | }
73 |
74 | @Override
75 | public void onSticker(Canvas canvas) {
76 | // empty
77 | }
78 |
79 | @Override
80 | public void registerCallback(Callback callback) {
81 | mCallback = callback;
82 | }
83 |
84 | @Override
85 | public void unregisterCallback(Callback callback) {
86 | mCallback = null;
87 | }
88 |
89 | @Override
90 | public boolean onRemove(V stickerView) {
91 | return mCallback != null && mCallback.onRemove(stickerView);
92 | }
93 |
94 | @Override
95 | public void onDismiss(V stickerView) {
96 | mFrame = null;
97 | stickerView.invalidate();
98 | if (mCallback != null) {
99 | mCallback.onDismiss(stickerView);
100 | }
101 | }
102 |
103 | @Override
104 | public void onShowing(V stickerView) {
105 | stickerView.invalidate();
106 | if (mCallback != null) {
107 | mCallback.onShowing(stickerView);
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/sticker/EditStickerMoveHelper.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.sticker
2 |
3 | import android.graphics.Matrix
4 | import android.view.MotionEvent
5 | import android.view.View
6 |
7 | /**
8 | *
9 | * @author ZeroCode
10 | * @date 2021/5/8 : 13:33
11 | */
12 | class EditStickerMoveHelper(private val mView: View) {
13 | private var mX = 0f
14 | private var mY = 0f
15 | fun onTouch(v: View, event: MotionEvent): Boolean {
16 | when (event.actionMasked) {
17 | MotionEvent.ACTION_DOWN -> {
18 | mX = event.x
19 | mY = event.y
20 | M.reset()
21 | M.setRotate(v.rotation)
22 | return true
23 | }
24 | MotionEvent.ACTION_MOVE -> {
25 | val dxy = floatArrayOf(event.x - mX, event.y - mY)
26 | M.mapPoints(dxy)
27 | v.translationX = mView.translationX + dxy[0]
28 | v.translationY = mView.translationY + dxy[1]
29 | return true
30 | }
31 | }
32 | return false
33 | }
34 |
35 | companion object {
36 | private const val TAG = "IMGStickerMoveHelper"
37 | private val M = Matrix()
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/sticker/EditStickerPortrait.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.sticker
2 |
3 | import android.graphics.Canvas
4 | import android.graphics.RectF
5 | import android.view.View
6 |
7 | /**
8 | *
9 | * @author ZeroCode
10 | * @date 2021/5/8 : 13:33
11 | */
12 | interface EditStickerPortrait {
13 | fun show(): Boolean
14 | fun remove(): Boolean
15 | fun dismiss(): Boolean
16 | val isShowing: Boolean
17 | val frame: RectF
18 |
19 | // RectF getAdjustFrame();
20 | //
21 | // RectF getDeleteFrame();
22 | fun onSticker(canvas: Canvas?)
23 | fun registerCallback(callback: Callback?)
24 | fun unregisterCallback(callback: Callback?)
25 | interface Callback {
26 | fun onDismiss(stickerView: V) where V : View?, V : EditSticker?
27 | fun onShowing(stickerView: V) where V : View?, V : EditSticker?
28 | fun onRemove(stickerView: V): Boolean where V : View?, V : EditSticker?
29 | }
30 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/sticker/EditStickerX.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.sticker;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Color;
5 | import android.graphics.Matrix;
6 | import android.graphics.Paint;
7 | import android.graphics.RectF;
8 | import android.view.MotionEvent;
9 |
10 | /**
11 | *
12 | * @author ZeroCode
13 | * @date 2021/5/17 : 14:16
14 | */
15 |
16 | public class EditStickerX {
17 |
18 | private float mBaseScale = 1f, mScale = 1f;
19 |
20 | private float mBaseRotate = 0f, mRotate = 0f;
21 |
22 | private float mX = 0f, mY = 0f;
23 |
24 | protected float[] mPivotXY = {0, 0};
25 |
26 | private StickerEvent mTouchEvent;
27 |
28 | private boolean isActivated = true;
29 |
30 | /**
31 | * isActivated 为true时,其坐标相对于屏幕左上角
32 | * isActivated 为false时,其坐标相对Image,切为单位坐标
33 | */
34 | protected RectF mFrame = new RectF();
35 |
36 | private RectF mRemoveFrame = new RectF();
37 |
38 | private RectF mAdjustFrame = new RectF();
39 |
40 | private final static float SIZE_ANCHOR = 60;
41 |
42 | private final static float STROKE_FRAME = 6f;
43 |
44 | private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
45 |
46 | {
47 | mPaint.setColor(Color.RED);
48 | mPaint.setStrokeWidth(STROKE_FRAME);
49 | mPaint.setStyle(Paint.Style.STROKE);
50 |
51 | mFrame.set(0, 0, SIZE_ANCHOR * 2, SIZE_ANCHOR * 2);
52 | mRemoveFrame.set(0, 0, SIZE_ANCHOR, SIZE_ANCHOR);
53 | mAdjustFrame.set(0, 0, SIZE_ANCHOR, SIZE_ANCHOR);
54 | }
55 |
56 | public boolean isActivated() {
57 | return isActivated;
58 | }
59 |
60 | public void setActivated(boolean activated) {
61 | isActivated = activated;
62 |
63 | }
64 |
65 | public void onMeasure(float width, float height) {
66 | mFrame.set(0, 0, width, height);
67 | mFrame.offset(mPivotXY[0] - mFrame.centerX(), mPivotXY[1] - mFrame.centerY());
68 | }
69 |
70 | public void onDraw(Canvas canvas) {
71 | if (isActivated) {
72 | canvas.save();
73 |
74 | canvas.rotate(mRotate, mPivotXY[0], mPivotXY[1]);
75 |
76 | canvas.drawRect(mFrame, mPaint);
77 |
78 | canvas.translate(mFrame.left, mFrame.top);
79 |
80 | canvas.drawRect(mRemoveFrame, mPaint);
81 |
82 | canvas.translate(mFrame.width() - mAdjustFrame.width(), mFrame.height() - mAdjustFrame.height());
83 |
84 | canvas.drawRect(mAdjustFrame, mPaint);
85 |
86 | canvas.restore();
87 | }
88 |
89 | canvas.rotate(mRotate, mPivotXY[0], mPivotXY[1]);
90 |
91 | // canvas.scale(mBaseScale * mScale, mBaseScale * mScale, mPivotXY[0], mPivotXY[1]);
92 | }
93 |
94 | public void setScale(float scale) {
95 | mScale = scale;
96 | }
97 |
98 | public void setRotate(float rotate) {
99 | mRotate = rotate;
100 | }
101 |
102 | public void setBaseScale(float baseScale) {
103 | mBaseScale = baseScale;
104 | }
105 |
106 | public void setBaseRotate(float baseRotate) {
107 | mBaseRotate = baseRotate;
108 | }
109 |
110 | public void offset(float dx, float dy) {
111 | mPivotXY[0] += dx;
112 | mPivotXY[1] += dy;
113 | mFrame.offset(mPivotXY[0] - mFrame.centerX(), mPivotXY[1] - mFrame.centerY());
114 | }
115 |
116 | public StickerEvent onTouch(MotionEvent event) {
117 | int action = event.getActionMasked();
118 |
119 | if (mTouchEvent == null && action != MotionEvent.ACTION_DOWN) {
120 | return null;
121 | }
122 |
123 | switch (action) {
124 | case MotionEvent.ACTION_DOWN:
125 | mX = event.getX();
126 | mY = event.getY();
127 | mTouchEvent = getTouchEvent(mX, mY);
128 |
129 | return mTouchEvent;
130 | case MotionEvent.ACTION_MOVE:
131 | if (mTouchEvent == StickerEvent.BODY) {
132 | offset(event.getX() - mX, event.getY() - mY);
133 | mX = event.getX();
134 | mY = event.getY();
135 | }
136 | default:
137 | return mTouchEvent;
138 | }
139 | }
140 |
141 | private StickerEvent getTouchEvent(float x, float y) {
142 | float[] xy = {x, y};
143 | Matrix matrix = new Matrix();
144 | matrix.setRotate(mRotate, mFrame.centerX(), mFrame.centerY());
145 | matrix.mapPoints(xy);
146 |
147 | if (mFrame.contains(xy[0], xy[1])) {
148 | if (isInsideRemove(xy[0], xy[1])) {
149 | // 触摸到删除按钮
150 | return mTouchEvent = StickerEvent.REMOVE;
151 | } else if (isInsideAdjust(xy[0], xy[1])) {
152 | // 触摸到调整按钮
153 | return mTouchEvent = StickerEvent.ADJUST;
154 | }
155 | return StickerEvent.BODY;
156 | }
157 | return null;
158 | }
159 |
160 | public void setTouchEvent(StickerEvent touchEvent) {
161 | mTouchEvent = touchEvent;
162 | }
163 |
164 | public boolean isInsideRemove(float x, float y) {
165 | return mRemoveFrame.contains(x - mFrame.left, y - mFrame.top);
166 | }
167 |
168 | public boolean isInsideAdjust(float x, float y) {
169 | return mAdjustFrame.contains(
170 | x - mFrame.right + mAdjustFrame.width(),
171 | y - mFrame.bottom + mAdjustFrame.height()
172 | );
173 | }
174 |
175 | public boolean isInside(float x, float y) {
176 | float[] xy = {x, y};
177 | Matrix matrix = new Matrix();
178 | matrix.setRotate(mRotate, mFrame.centerX(), mFrame.centerY());
179 | matrix.mapPoints(xy);
180 |
181 | return mFrame.contains(xy[0], xy[1]);
182 | }
183 |
184 | public void transform(Matrix matrix) {
185 | matrix.mapPoints(mPivotXY);
186 | mFrame.offset(mPivotXY[0] - mFrame.centerX(), mPivotXY[1] - mFrame.centerY());
187 | }
188 |
189 | public enum StickerEvent {
190 | REMOVE,
191 | BODY,
192 | ADJUST
193 | }
194 | }
195 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/ui/text/EditImageText.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.ui.text
2 |
3 | import android.graphics.Color
4 | import android.text.TextUtils
5 |
6 | /**
7 | * IMGText
8 | * @author ZeroCode
9 | * @date 2021/5/8 : 13:35
10 | */
11 | class EditImageText(var text: String, color: Int) {
12 | var color = Color.WHITE
13 |
14 | var backgroundColor:Int=Color.TRANSPARENT
15 |
16 | val isEmpty: Boolean
17 | get() = TextUtils.isEmpty(text)
18 |
19 | fun length(): Int {
20 | return if (isEmpty) 0 else text.length
21 | }
22 |
23 | override fun toString(): String {
24 | return "IMGText{" +
25 | "text='" + text + '\'' +
26 | ", color=" + color +
27 | '}'
28 | }
29 |
30 | init {
31 | this.color = color
32 | }
33 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/ui/text/EditTextEditDialog.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.ui.text;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.graphics.Color;
6 | import android.os.Bundle;
7 | import android.text.Editable;
8 | import android.text.Spannable;
9 | import android.text.SpannableStringBuilder;
10 | import android.text.TextWatcher;
11 | import android.text.style.BackgroundColorSpan;
12 | import android.view.View;
13 | import android.view.Window;
14 | import android.view.WindowManager.LayoutParams;
15 | import android.widget.EditText;
16 | import android.widget.ImageView;
17 | import android.widget.RadioGroup;
18 | import android.widget.TextView;
19 |
20 | import com.zero_code.libEdImage.R;
21 | import com.zero_code.libEdImage.view.EditColorGroup;
22 |
23 |
24 | /**
25 | *
26 | * @author ZeroCode
27 | * @date 2021/5/17 : 14:16
28 | */
29 |
30 | public class EditTextEditDialog extends Dialog implements View.OnClickListener,
31 | RadioGroup.OnCheckedChangeListener, TextWatcher {
32 |
33 | private static final String TAG = "IMGTextEditDialog";
34 |
35 | private EditText mEditText;
36 |
37 | private int textBgColor = Color.TRANSPARENT;
38 |
39 | private Callback mCallback;
40 |
41 | private EditImageText mDefaultText;
42 |
43 | private EditColorGroup mColorGroup;
44 |
45 | private TextView mTextView;
46 |
47 | private ImageView imageEd;
48 |
49 | private Boolean isBackground = false;
50 |
51 | public EditTextEditDialog(Context context, Callback callback) {
52 | super(context, R.style.ImageTextDialog);
53 | setContentView(R.layout.image_text_dialog);
54 | mCallback = callback;
55 | Window window = getWindow();
56 | if (window != null) {
57 | window.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
58 | }
59 | }
60 |
61 | @Override
62 | protected void onCreate(Bundle savedInstanceState) {
63 | super.onCreate(savedInstanceState);
64 |
65 | mColorGroup = findViewById(R.id.cg_colors);
66 | mTextView = findViewById(R.id.tv_text);
67 | mColorGroup.setVisibility(View.VISIBLE);
68 | mColorGroup.setOnCheckedChangeListener(this);
69 | mEditText = findViewById(R.id.et_text);
70 | imageEd = findViewById(R.id.image_is_ed_prospect);
71 |
72 | findViewById(R.id.tv_cancel).setOnClickListener(this);
73 | findViewById(R.id.tv_done).setOnClickListener(this);
74 | findViewById(R.id.tv_empty).setOnClickListener(this);
75 | imageEd.setOnClickListener(this);
76 | //R.color.title_font_color_right
77 | mEditText.addTextChangedListener(this);
78 |
79 |
80 | }
81 |
82 | @Override
83 | protected void onStart() {
84 | super.onStart();
85 | if (mDefaultText != null) {
86 | mEditText.setText(mDefaultText.getText());
87 | mEditText.setTextColor(mDefaultText.getColor());
88 | mTextView.setTextColor(mDefaultText.getColor());
89 | if (!mDefaultText.isEmpty()) {
90 | mEditText.setSelection(mEditText.length());
91 | }
92 | mDefaultText = null;
93 | } else mEditText.setText("");
94 |
95 |
96 | // mColorGroup.setCheckColor(mEditText.getCurrentTextColor());
97 |
98 | }
99 |
100 | public void setText(EditImageText text) {
101 | mDefaultText = text;
102 | }
103 |
104 | public void reset() {
105 | setText(new EditImageText(null, Color.WHITE));
106 | }
107 |
108 | @Override
109 | public void onClick(View v) {
110 | int vid = v.getId();
111 |
112 | if (vid == R.id.tv_done) {
113 | onDone();
114 | } else if (vid == R.id.tv_cancel) {
115 | dismiss();
116 | } else if (vid == R.id.tv_empty) {
117 | mEditText.setText("");
118 | } else if (vid == R.id.image_is_ed_prospect){
119 | isBackground=!isBackground;
120 | mColorGroup.setCheckColor(Color.RED);
121 | }
122 | }
123 |
124 | private void onDone() {
125 | String text = mEditText.getText().toString();
126 | if (mCallback != null) {
127 | EditImageText imgText = new EditImageText(text, mEditText.getCurrentTextColor());
128 | imgText.setBackgroundColor(textBgColor);
129 | mCallback.onText(imgText);
130 | }
131 | dismiss();
132 | }
133 |
134 | @Override
135 | public void onCheckedChanged(RadioGroup group, int checkedId) {
136 | if (!isBackground) {
137 | mEditText.setTextColor(mColorGroup.getCheckColor());
138 | mTextView.setTextColor(mColorGroup.getCheckColor());
139 | } else {
140 | textBgColor=mColorGroup.getCheckColor();
141 | String s = mTextView.getText().toString();
142 | SpannableStringBuilder style = new SpannableStringBuilder(s);
143 | style.setSpan(new BackgroundColorSpan(textBgColor), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
144 | mTextView.setText(style);
145 | }
146 |
147 | }
148 |
149 | @Override
150 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
151 |
152 | }
153 |
154 | @Override
155 | public void onTextChanged(CharSequence s, int start, int before, int count) {
156 |
157 | }
158 |
159 | @Override
160 | public void afterTextChanged(Editable s) {
161 | SpannableStringBuilder style = new SpannableStringBuilder(s);
162 | style.setSpan(new BackgroundColorSpan(textBgColor), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
163 | mTextView.setText(style);
164 | }
165 |
166 | public interface Callback {
167 |
168 | void onText(EditImageText text);
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/view/Bean.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.view
2 |
3 |
4 |
5 |
6 | /**
7 | * 编辑页面 底部 工具局域栏实体
8 | */
9 | data class EditImageToolsBean(
10 | val res:IntArray = IntArray(2), //图片资源 0 是选中了 1是未选中
11 | var isSelected:Boolean=false //是否选中
12 | ){
13 | fun getImage():Int{
14 | return if (isSelected) res[0] else res[1]
15 | }
16 |
17 | override fun equals(other: Any?): Boolean {
18 | if (this === other) return true
19 | if (javaClass != other?.javaClass) return false
20 |
21 | other as EditImageToolsBean
22 |
23 | if (!res.contentEquals(other.res)) return false
24 | if (isSelected != other.isSelected) return false
25 |
26 | return true
27 | }
28 |
29 | override fun hashCode(): Int {
30 | var result = res.contentHashCode()
31 | result = 31 * result + isSelected.hashCode()
32 | return result
33 | }
34 | }
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/view/EditColorGroup.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.util.AttributeSet;
6 | import android.widget.RadioGroup;
7 |
8 |
9 |
10 | public class EditColorGroup extends RadioGroup {
11 |
12 | public EditColorGroup(Context context) {
13 | super(context);
14 | }
15 |
16 | public EditColorGroup(Context context, AttributeSet attrs) {
17 | super(context, attrs);
18 | }
19 |
20 | public int getCheckColor() {
21 | int checkedId = getCheckedRadioButtonId();
22 | EditColorRadio radio = findViewById(checkedId);
23 | if (radio != null) {
24 | return radio.getColor();
25 | }
26 | return Color.WHITE;
27 | }
28 |
29 | public void setCheckColor(int color) {
30 | int count = getChildCount();
31 | for (int i = 0; i < count; i++) {
32 | EditColorRadio radio = (EditColorRadio) getChildAt(i);
33 | if (radio.getColor() == color) {
34 | radio.setChecked(true);
35 | break;
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/view/EditColorRadio.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.view;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.Paint;
9 | import android.util.AttributeSet;
10 | import android.view.animation.AccelerateDecelerateInterpolator;
11 |
12 | import com.zero_code.libEdImage.R;
13 |
14 |
15 |
16 |
17 | public class EditColorRadio extends androidx.appcompat.widget.AppCompatRadioButton implements ValueAnimator.AnimatorUpdateListener {
18 |
19 | private static final String TAG = "IMGColorRadio";
20 |
21 | private int mColor = Color.WHITE;
22 |
23 | private int mStrokeColor = Color.WHITE;
24 |
25 | private float mRadiusRatio = 0f;
26 |
27 | private ValueAnimator mAnimator;
28 |
29 | private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
30 |
31 | private static final float RADIUS_BASE = 0.4f;
32 |
33 | private static final float RADIUS_RING = 0.9f;
34 |
35 | private static final float RADIUS_BALL = 0.6f;
36 |
37 | public EditColorRadio(Context context) {
38 | this(context, null, 0);
39 | }
40 |
41 | public EditColorRadio(Context context, AttributeSet attrs) {
42 | super(context, attrs);
43 | initialize(context, attrs, 0);
44 | }
45 |
46 | public EditColorRadio(Context context, AttributeSet attrs, int defStyleAttr) {
47 | super(context, attrs, defStyleAttr);
48 | initialize(context, attrs, defStyleAttr);
49 | }
50 |
51 | private void initialize(Context context, AttributeSet attrs, int defStyleAttr) {
52 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IMGColorRadio);
53 |
54 | mColor = a.getColor(R.styleable.IMGColorRadio_image_color, Color.WHITE);
55 | mStrokeColor = a.getColor(R.styleable.IMGColorRadio_image_stroke_color, Color.WHITE);
56 |
57 | a.recycle();
58 |
59 | setButtonDrawable(null);
60 |
61 | mPaint.setColor(mColor);
62 | mPaint.setStrokeWidth(5f);
63 | }
64 |
65 | private ValueAnimator getAnimator() {
66 | if (mAnimator == null) {
67 | mAnimator = ValueAnimator.ofFloat(0f, 1f);
68 | mAnimator.addUpdateListener(this);
69 | mAnimator.setDuration(200);
70 | mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
71 | }
72 | return mAnimator;
73 | }
74 |
75 | public void setColor(int color) {
76 | mColor = color;
77 | mPaint.setColor(mColor);
78 | }
79 |
80 | public int getColor() {
81 | return mColor;
82 | }
83 |
84 | @Override
85 | public void draw(Canvas canvas) {
86 | super.draw(canvas);
87 |
88 | float hw = getWidth() / 2f, hh = getHeight() / 2f;
89 | float radius = Math.min(hw, hh);
90 |
91 | canvas.save();
92 | mPaint.setColor(mColor);
93 | mPaint.setStyle(Paint.Style.FILL);
94 | canvas.drawCircle(hw, hh, getBallRadius(radius), mPaint);
95 |
96 | mPaint.setColor(mStrokeColor);
97 | mPaint.setStyle(Paint.Style.STROKE);
98 | canvas.drawCircle(hw, hh, getRingRadius(radius), mPaint);
99 | canvas.restore();
100 | }
101 |
102 | private float getBallRadius(float radius) {
103 | return radius * ((RADIUS_BALL - RADIUS_BASE) * mRadiusRatio + RADIUS_BASE);
104 | }
105 |
106 | private float getRingRadius(float radius) {
107 | return radius * ((RADIUS_RING - RADIUS_BASE) * mRadiusRatio + RADIUS_BASE);
108 | }
109 |
110 | @Override
111 | public void setChecked(boolean checked) {
112 | boolean isChanged = checked != isChecked();
113 |
114 | super.setChecked(checked);
115 |
116 | if (isChanged) {
117 | ValueAnimator animator = getAnimator();
118 |
119 | if (checked) {
120 | animator.start();
121 | } else {
122 | animator.reverse();
123 | }
124 | }
125 | }
126 |
127 | @Override
128 | public void onAnimationUpdate(ValueAnimator animation) {
129 | mRadiusRatio = (float) animation.getAnimatedValue();
130 | invalidate();
131 | }
132 |
133 |
134 |
135 | }
136 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/view/EditMosaicGroup.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.view;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.RadioGroup;
6 |
7 | /**
8 | * 马赛克专用
9 | * @author ZeroCode
10 | * @date 2021/5/10 : 16:04
11 | */
12 | public class EditMosaicGroup extends RadioGroup {
13 |
14 | /**
15 | * 0.2-0.6
16 | */
17 | public static final Float IMG_MOSAIC_SIZE_1=0.2F;
18 | public static final Float IMG_MOSAIC_SIZE_2=0.3F;
19 | public static final Float IMG_MOSAIC_SIZE_3=0.4F;
20 | public static final Float IMG_MOSAIC_SIZE_4=0.5F;
21 | public static final Float IMG_MOSAIC_SIZE_5=0.6F;
22 | public static final Float IMG_MOSAIC_SIZE_NO=-1F;
23 |
24 | public EditMosaicGroup(Context context) {
25 | super(context);
26 | }
27 |
28 | public EditMosaicGroup(Context context, AttributeSet attrs) {
29 | super(context, attrs);
30 | }
31 |
32 | public Float getCheckSize() {
33 | int checkedId = getCheckedRadioButtonId();
34 | EditMosaicRadio radio = findViewById(checkedId);
35 | if (radio != null) {
36 | return radio.getSize();
37 | }
38 | return IMG_MOSAIC_SIZE_NO;
39 | }
40 |
41 | public void setCheckSize(Float size) {
42 | int count = getChildCount();
43 | for (int i = 0; i < count; i++) {
44 | EditMosaicRadio radio = (EditMosaicRadio) getChildAt(i);
45 | if (Math.abs(radio.getSize() - size)>=0) {
46 | radio.setChecked(true);
47 | break;
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/view/EditMosaicRadio.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.view;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.Paint;
9 | import android.util.AttributeSet;
10 | import android.view.animation.AccelerateDecelerateInterpolator;
11 |
12 | import com.zero_code.libEdImage.R;
13 |
14 | /**
15 | * IMGMosaicRadio
16 | *
17 | * @author ZeroCode
18 | * @date 2021/5/10 : 16:05
19 | */
20 | public class EditMosaicRadio extends androidx.appcompat.widget.AppCompatRadioButton implements
21 | ValueAnimator.AnimatorUpdateListener {
22 |
23 | private static final String TAG = "IMGMosaicRadio";
24 |
25 | private int mColor = Color.WHITE;
26 |
27 | private int mStrokeColor = Color.WHITE;
28 |
29 | private float mRadiusRatio = 0f;
30 |
31 | private ValueAnimator mAnimator;
32 |
33 | private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
34 |
35 | private float RADIUS_BASE = 0.1f;
36 |
37 | private float RADIUS_RING = 0.9f;
38 |
39 | private float RADIUS_BALL = 0.1f;
40 |
41 | public EditMosaicRadio(Context context) {
42 | this(context, null, 0);
43 | }
44 |
45 | public EditMosaicRadio(Context context, AttributeSet attrs) {
46 | super(context, attrs);
47 | initialize(context, attrs, 0);
48 | }
49 |
50 | public EditMosaicRadio(Context context, AttributeSet attrs, int defStyleAttr) {
51 | super(context, attrs, defStyleAttr);
52 | initialize(context, attrs, defStyleAttr);
53 | }
54 |
55 | private void initialize(Context context, AttributeSet attrs, int defStyleAttr) {
56 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IMGMosaicRadio);
57 | RADIUS_BASE = a.getFloat(R.styleable.IMGMosaicRadio_image_unselected_size, 0.1f);
58 | RADIUS_BALL = a.getFloat(R.styleable.IMGMosaicRadio_image_selected_size, 0.1f);
59 |
60 | a.recycle();
61 |
62 | setButtonDrawable(null);
63 |
64 | mPaint.setColor(mColor);
65 | mPaint.setStrokeWidth(5f);
66 | }
67 |
68 | private ValueAnimator getAnimator() {
69 | if (mAnimator == null) {
70 | mAnimator = ValueAnimator.ofFloat(0f, 1f);
71 | mAnimator.addUpdateListener(this);
72 | mAnimator.setDuration(200);
73 | mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
74 | }
75 | return mAnimator;
76 | }
77 |
78 |
79 |
80 | @Override
81 | public void draw(Canvas canvas) {
82 | super.draw(canvas);
83 |
84 | float hw = getWidth() / 2f, hh = getHeight() / 2f;
85 | float radius = Math.min(hw, hh);
86 |
87 | canvas.save();
88 | mPaint.setColor(mColor);
89 | mPaint.setStyle(Paint.Style.FILL);
90 | canvas.drawCircle(hw, hh, getBallRadius(radius), mPaint);
91 |
92 | mPaint.setColor(mStrokeColor);
93 | mPaint.setStyle(Paint.Style.STROKE);
94 | canvas.drawCircle(hw, hh, getRingRadius(radius), mPaint);
95 | canvas.restore();
96 | }
97 |
98 | private float getBallRadius(float radius) {
99 | return radius * ((RADIUS_BALL - RADIUS_BASE) * mRadiusRatio + RADIUS_BASE);
100 | }
101 |
102 | private float getRingRadius(float radius) {
103 | return radius * ((RADIUS_RING - RADIUS_BASE) * mRadiusRatio + RADIUS_BASE);
104 | }
105 |
106 | @Override
107 | public void setChecked(boolean checked) {
108 | boolean isChanged = checked != isChecked();
109 |
110 | super.setChecked(checked);
111 |
112 | if (isChanged) {
113 | ValueAnimator animator = getAnimator();
114 |
115 | if (checked) {
116 | animator.start();
117 | mStrokeColor=Color.parseColor("#007EFA");
118 | } else {
119 | animator.reverse();
120 | mStrokeColor=Color.WHITE;
121 | }
122 | }
123 | }
124 |
125 | @Override
126 | public void onAnimationUpdate(ValueAnimator animation) {
127 | mRadiusRatio = (float) animation.getAnimatedValue();
128 | invalidate();
129 | }
130 |
131 | public Float getSize() {
132 | return RADIUS_BASE;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/view/PathArrows.kt:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.view
2 |
3 | import android.graphics.Paint
4 |
5 | data class PathArrows(
6 | var start: ArrowsCoordinate, //开始坐标
7 | var end: ArrowsCoordinate, //结束坐标
8 | var mColor: Int, //颜色
9 | var size: Int //大小
10 | ) {
11 |
12 | val mPaint: Paint = Paint().apply {
13 | color = mColor
14 | }
15 | }
16 |
17 |
18 | data class ArrowsCoordinate(
19 | val x: Float,
20 | val y: Float
21 | )
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/widget/EditStickerAdjustHelper.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.widget;
2 |
3 | import android.graphics.Matrix;
4 | import android.util.Log;
5 | import android.view.MotionEvent;
6 | import android.view.View;
7 |
8 | import static com.zero_code.libEdImage.ImageConfigKt.IS_DEBUG;
9 |
10 | /**
11 | * @author ZeroCode
12 | * @date 2021/5/17 : 14:16
13 | */
14 |
15 | public class EditStickerAdjustHelper implements View.OnTouchListener {
16 |
17 | private static final String TAG = "EditStickerAdjustHelper";
18 |
19 | private View mView;
20 |
21 | private EditStickerView mContainer;
22 |
23 | private float mCenterX, mCenterY;
24 |
25 | private double mRadius, mDegrees;
26 |
27 | private Matrix M = new Matrix();
28 |
29 | public EditStickerAdjustHelper(EditStickerView container, View view) {
30 | mView = view;
31 | mContainer = container;
32 | mView.setOnTouchListener(this);
33 | }
34 |
35 | @Override
36 | public boolean onTouch(View v, MotionEvent event) {
37 | switch (event.getAction()) {
38 | case MotionEvent.ACTION_DOWN:
39 |
40 | float x = event.getX();
41 |
42 | float y = event.getY();
43 |
44 | mCenterX = mCenterY = 0;
45 |
46 | float pointX = mView.getX() + x - mContainer.getPivotX();
47 |
48 | float pointY = mView.getY() + y - mContainer.getPivotY();
49 | if (IS_DEBUG) {
50 | Log.d(TAG, String.format("X=%f,Y=%f", pointX, pointY));
51 | }
52 |
53 | mRadius = toLength(0, 0, pointX, pointY);
54 |
55 | mDegrees = toDegrees(pointY, pointX);
56 |
57 | M.setTranslate(pointX - x, pointY - y);
58 |
59 | if (IS_DEBUG)
60 | Log.d(TAG, String.format("degrees=%f", toDegrees(pointY, pointX)));
61 |
62 | M.postRotate((float) -toDegrees(pointY, pointX), mCenterX, mCenterY);
63 |
64 | return true;
65 |
66 | case MotionEvent.ACTION_MOVE:
67 |
68 | float[] xy = {event.getX(), event.getY()};
69 |
70 | pointX = mView.getX() + xy[0] - mContainer.getPivotX();
71 |
72 | pointY = mView.getY() + xy[1] - mContainer.getPivotY();
73 | if (IS_DEBUG)
74 | Log.d(TAG, String.format("X=%f,Y=%f", pointX, pointY));
75 |
76 | double radius = toLength(0, 0, pointX, pointY);
77 |
78 | double degrees = toDegrees(pointY, pointX);
79 |
80 | float scale = (float) (radius / mRadius);
81 |
82 |
83 | mContainer.addScale(scale);
84 | if (IS_DEBUG)
85 | Log.d(TAG, " D = " + (degrees - mDegrees));
86 |
87 | mContainer.setRotation((float) (mContainer.getRotation() + degrees - mDegrees));
88 |
89 | mRadius = radius;
90 |
91 | return true;
92 | }
93 | return false;
94 | }
95 |
96 | private static double toDegrees(float v, float v1) {
97 | return Math.toDegrees(Math.atan2(v, v1));
98 | }
99 |
100 | private static double toLength(float x1, float y1, float x2, float y2) {
101 | return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/widget/EditStickerTextView.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.util.AttributeSet;
6 | import android.util.TypedValue;
7 | import android.view.View;
8 | import android.widget.TextView;
9 |
10 | import com.zero_code.libEdImage.ui.text.EditImageText;
11 | import com.zero_code.libEdImage.ui.text.EditTextEditDialog;
12 |
13 |
14 | /**
15 | *
16 | * @author ZeroCode
17 | * @date 2021/5/17 : 14:16
18 | */
19 | public class EditStickerTextView extends EditStickerView implements EditTextEditDialog.Callback {
20 |
21 | private static final String TAG = "IMGStickerTextView";
22 |
23 | private TextView mTextView;
24 |
25 | private EditImageText mText;
26 |
27 | private EditTextEditDialog mDialog;
28 |
29 | private static float mBaseTextSize = -1f;
30 |
31 | private static final int PADDING = 26;
32 |
33 | private static final float TEXT_SIZE_SP = 24f;
34 |
35 | public EditStickerTextView(Context context) {
36 | this(context, null, 0);
37 | }
38 |
39 | public EditStickerTextView(Context context, AttributeSet attrs) {
40 | this(context, attrs, 0);
41 | }
42 |
43 | public EditStickerTextView(Context context, AttributeSet attrs, int defStyleAttr) {
44 | super(context, attrs, defStyleAttr);
45 | }
46 |
47 | @Override
48 | public void onInitialize(Context context) {
49 | if (mBaseTextSize <= 0) {
50 | mBaseTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
51 | TEXT_SIZE_SP, context.getResources().getDisplayMetrics());
52 | }
53 | super.onInitialize(context);
54 | }
55 |
56 | @Override
57 | public View onCreateContentView(Context context) {
58 | mTextView = new TextView(context);
59 | mTextView.setTextSize(mBaseTextSize);
60 | mTextView.setPadding(PADDING, PADDING, PADDING, PADDING);
61 | mTextView.setTextColor(Color.WHITE);
62 |
63 | return mTextView;
64 | }
65 |
66 | public void setText(EditImageText text) {
67 | mText = text;
68 | if (mText != null && mTextView != null) {
69 | mTextView.setText(mText.getText());
70 | mTextView.setTextColor(mText.getColor());
71 | }
72 | }
73 |
74 | public EditImageText getText() {
75 | return mText;
76 | }
77 |
78 | @Override
79 | public void onContentTap() {
80 | EditTextEditDialog dialog = getDialog();
81 | dialog.setText(mText);
82 | dialog.show();
83 | }
84 |
85 | private EditTextEditDialog getDialog() {
86 | if (mDialog == null) {
87 | mDialog = new EditTextEditDialog(getContext(), this);
88 | }
89 | return mDialog;
90 | }
91 |
92 | @Override
93 | public void onText(EditImageText text) {
94 | mText = text;
95 | if (mText != null && mTextView != null) {
96 | mTextView.setText(mText.getText());
97 | mTextView.setBackgroundColor(text.getBackgroundColor());
98 | mTextView.setTextColor(mText.getColor());
99 | }
100 | }
101 | }
--------------------------------------------------------------------------------
/lib_edImage/src/main/java/com/zero_code/libEdImage/widget/EditStickerView.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage.widget;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Matrix;
8 | import android.graphics.Paint;
9 | import android.graphics.Rect;
10 | import android.graphics.RectF;
11 | import android.util.AttributeSet;
12 | import android.view.MotionEvent;
13 | import android.view.View;
14 | import android.view.ViewConfiguration;
15 | import android.view.ViewGroup;
16 | import android.widget.ImageView;
17 |
18 | import com.zero_code.libEdImage.R;
19 | import com.zero_code.libEdImage.sticker.EditSticker;
20 | import com.zero_code.libEdImage.sticker.EditStickerHelper;
21 | import com.zero_code.libEdImage.sticker.EditStickerMoveHelper;
22 |
23 |
24 | /**
25 | *
26 | * @author ZeroCode
27 | * @date 2021/5/17 : 14:16
28 | */
29 |
30 | @SuppressLint("ResourceAsColor")
31 | public abstract class EditStickerView extends ViewGroup implements EditSticker, View.OnClickListener {
32 |
33 | private static final String TAG = "EditStickerView";
34 |
35 | private View mContentView;
36 |
37 | private float mScale = 1f;
38 |
39 | // TODO
40 | private int mDownShowing = 0;
41 |
42 | private EditStickerMoveHelper mMoveHelper;
43 |
44 | private EditStickerHelper mStickerHelper;
45 |
46 | private ImageView mRemoveView, mAdjustView;
47 |
48 | private float mMaxScaleValue = MAX_SCALE_VALUE;
49 |
50 | private Paint PAINT;
51 |
52 | private Matrix mMatrix = new Matrix();
53 |
54 | private RectF mFrame = new RectF();
55 |
56 | private Rect mTempFrame = new Rect();
57 |
58 | private static final float MAX_SCALE_VALUE = 4f;
59 |
60 | private static final int ANCHOR_SIZE = 48;
61 |
62 | private static final int ANCHOR_SIZE_HALF = ANCHOR_SIZE >> 1;
63 |
64 | private static final float STROKE_WIDTH = 3f;
65 |
66 | {
67 | PAINT = new Paint(Paint.ANTI_ALIAS_FLAG);
68 | PAINT.setColor(R.color.title_font_color_right);
69 | PAINT.setStyle(Paint.Style.STROKE);
70 | PAINT.setStrokeWidth(STROKE_WIDTH);
71 | }
72 |
73 | public EditStickerView(Context context) {
74 | this(context, null, 0);
75 | }
76 |
77 | public EditStickerView(Context context, AttributeSet attrs) {
78 | this(context, attrs, 0);
79 | }
80 |
81 | public EditStickerView(Context context, AttributeSet attrs, int defStyleAttr) {
82 | super(context, attrs, defStyleAttr);
83 | onInitialize(context);
84 | }
85 |
86 | public void onInitialize(Context context) {
87 | setBackgroundColor(Color.TRANSPARENT);
88 |
89 | mContentView = onCreateContentView(context);
90 | addView(mContentView, getContentLayoutParams());
91 |
92 | mRemoveView = new ImageView(context);
93 | mRemoveView.setScaleType(ImageView.ScaleType.FIT_XY);
94 | mRemoveView.setImageResource(R.mipmap.image_ic_delete);
95 | addView(mRemoveView, getAnchorLayoutParams());
96 | mRemoveView.setOnClickListener(this);
97 |
98 | mAdjustView = new ImageView(context);
99 | mAdjustView.setScaleType(ImageView.ScaleType.FIT_XY);
100 | mAdjustView.setImageResource(R.mipmap.image_ic_adjust);
101 | addView(mAdjustView, getAnchorLayoutParams());
102 |
103 | new EditStickerAdjustHelper(this, mAdjustView);
104 |
105 | mStickerHelper = new EditStickerHelper<>(this);
106 | mMoveHelper = new EditStickerMoveHelper(this);
107 | }
108 |
109 | public abstract View onCreateContentView(Context context);
110 |
111 | @Override
112 | public float getScale() {
113 | return mScale;
114 | }
115 |
116 | @Override
117 | public void setScale(float scale) {
118 | mScale = scale;
119 |
120 | mContentView.setScaleX(mScale);
121 | mContentView.setScaleY(mScale);
122 |
123 | int pivotX = (getLeft() + getRight()) >> 1;
124 | int pivotY = (getTop() + getBottom()) >> 1;
125 |
126 | mFrame.set(pivotX, pivotY, pivotX, pivotY);
127 | mFrame.inset(-(mContentView.getMeasuredWidth() >> 1), -(mContentView.getMeasuredHeight() >> 1));
128 |
129 | mMatrix.setScale(mScale, mScale, mFrame.centerX(), mFrame.centerY());
130 | mMatrix.mapRect(mFrame);
131 |
132 | mFrame.round(mTempFrame);
133 |
134 | layout(mTempFrame.left, mTempFrame.top, mTempFrame.right, mTempFrame.bottom);
135 | }
136 |
137 | @Override
138 | public void addScale(float scale) {
139 | setScale(getScale() * scale);
140 | }
141 |
142 | private LayoutParams getContentLayoutParams() {
143 | return new LayoutParams(
144 | LayoutParams.WRAP_CONTENT,
145 | LayoutParams.WRAP_CONTENT
146 | );
147 | }
148 |
149 | private LayoutParams getAnchorLayoutParams() {
150 | return new LayoutParams(ANCHOR_SIZE, ANCHOR_SIZE);
151 | }
152 |
153 | @Override
154 | public void draw(Canvas canvas) {
155 | if (isShowing()) {
156 | canvas.drawRect(ANCHOR_SIZE_HALF, ANCHOR_SIZE_HALF,
157 | getWidth() - ANCHOR_SIZE_HALF,
158 | getHeight() - ANCHOR_SIZE_HALF, PAINT);
159 | }
160 | super.draw(canvas);
161 | }
162 |
163 | @Override
164 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
165 | int count = getChildCount();
166 |
167 | int maxHeight = 0;
168 | int maxWidth = 0;
169 | int childState = 0;
170 |
171 | for (int i = 0; i < count; i++) {
172 | final View child = getChildAt(i);
173 | if (child.getVisibility() != GONE) {
174 | child.measure(widthMeasureSpec, heightMeasureSpec);
175 |
176 | maxWidth = Math.round(Math.max(maxWidth, child.getMeasuredWidth() * child.getScaleX()));
177 | maxHeight = Math.round(Math.max(maxHeight, child.getMeasuredHeight() * child.getScaleY()));
178 |
179 | childState = combineMeasuredStates(childState, child.getMeasuredState());
180 | }
181 | }
182 |
183 | maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
184 | maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
185 |
186 | setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
187 | resolveSizeAndState(maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT));
188 | }
189 |
190 | @Override
191 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
192 |
193 | mFrame.set(left, top, right, bottom);
194 |
195 | int count = getChildCount();
196 | if (count == 0) {
197 | return;
198 | }
199 |
200 | mRemoveView.layout(0, 0, mRemoveView.getMeasuredWidth(), mRemoveView.getMeasuredHeight());
201 | mAdjustView.layout(
202 | right - left - mAdjustView.getMeasuredWidth(),
203 | bottom - top - mAdjustView.getMeasuredHeight(),
204 | right - left, bottom - top
205 | );
206 |
207 | int centerX = (right - left) >> 1, centerY = (bottom - top) >> 1;
208 | int hw = mContentView.getMeasuredWidth() >> 1;
209 | int hh = mContentView.getMeasuredHeight() >> 1;
210 |
211 | mContentView.layout(centerX - hw, centerY - hh, centerX + hw, centerY + hh);
212 | }
213 |
214 | @Override
215 | protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
216 | return isShowing() && super.drawChild(canvas, child, drawingTime);
217 | }
218 |
219 | @Override
220 | public boolean onInterceptTouchEvent(MotionEvent ev) {
221 | if (!isShowing() && ev.getAction() == MotionEvent.ACTION_DOWN) {
222 | mDownShowing = 0;
223 | show();
224 | return true;
225 | }
226 | return isShowing() && super.onInterceptTouchEvent(ev);
227 | }
228 |
229 | @Override
230 | public boolean onTouchEvent(MotionEvent event) {
231 |
232 | boolean handled = mMoveHelper.onTouch(this, event);
233 |
234 | switch (event.getActionMasked()) {
235 | case MotionEvent.ACTION_DOWN:
236 | mDownShowing++;
237 | break;
238 | case MotionEvent.ACTION_UP:
239 | if (mDownShowing > 1 && event.getEventTime() - event.getDownTime() < ViewConfiguration.getTapTimeout()) {
240 | onContentTap();
241 | return true;
242 | }
243 | break;
244 | }
245 |
246 | return handled | super.onTouchEvent(event);
247 | }
248 |
249 | @Override
250 | public void onClick(View v) {
251 | if (v == mRemoveView) {
252 | onRemove();
253 | }
254 | }
255 |
256 | public void onRemove() {
257 | mStickerHelper.remove();
258 | }
259 |
260 | public void onContentTap() {
261 |
262 | }
263 |
264 | @Override
265 | public boolean show() {
266 | return mStickerHelper.show();
267 | }
268 |
269 | @Override
270 | public boolean remove() {
271 | return mStickerHelper.remove();
272 | }
273 |
274 | @Override
275 | public boolean dismiss() {
276 | return mStickerHelper.dismiss();
277 | }
278 |
279 | @Override
280 | public boolean isShowing() {
281 | return mStickerHelper.isShowing();
282 | }
283 |
284 | @Override
285 | public RectF getFrame() {
286 | return mStickerHelper.getFrame();
287 | }
288 |
289 | @Override
290 | public void onSticker(Canvas canvas) {
291 | canvas.translate(mContentView.getX(), mContentView.getY());
292 | mContentView.draw(canvas);
293 | }
294 |
295 | @Override
296 | public void registerCallback(Callback callback) {
297 | mStickerHelper.registerCallback(callback);
298 | }
299 |
300 | @Override
301 | public void unregisterCallback(Callback callback) {
302 | mStickerHelper.unregisterCallback(callback);
303 | }
304 | }
305 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/anim/image_dialog_enter.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
14 |
15 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/anim/image_dialog_exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
14 |
15 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/anim/image_fade_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/anim/image_fade_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/color/image_color_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/layout/activity_edit_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
18 |
19 |
20 |
27 |
28 |
29 |
33 |
34 |
43 |
44 |
52 |
53 |
54 |
63 |
64 |
65 |
66 |
67 |
75 |
76 |
77 |
78 |
79 |
81 |
82 |
83 |
84 |
86 |
87 |
88 |
89 |
90 |
96 |
97 |
98 |
104 |
105 |
106 |
110 |
111 |
119 |
120 |
128 |
129 |
137 |
138 |
146 |
147 |
148 |
149 |
150 |
159 |
160 |
161 |
172 |
173 |
174 |
185 |
186 |
187 |
188 |
189 |
190 |
197 |
198 |
199 |
205 |
206 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/layout/app_item_null.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
9 |
12 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/layout/image_arrows_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
23 |
24 |
31 |
32 |
39 |
40 |
47 |
48 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/layout/image_color_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
23 |
24 |
29 |
30 |
35 |
36 |
41 |
42 |
47 |
48 |
53 |
54 |
59 |
60 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/layout/image_mosaic_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
23 |
24 |
31 |
32 |
39 |
40 |
47 |
48 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/layout/image_text_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
15 |
26 |
27 |
28 |
38 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
60 |
61 |
62 |
63 |
69 |
70 |
81 |
82 |
83 |
95 |
96 |
97 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/layout/item_edit_image_tools_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_arrow.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_arrowed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_arrowed.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_close.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_cut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_cut.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_cuted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_cuted.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_free.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_free.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_freed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_freed.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_left.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_level.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_level.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_mosaic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_mosaic.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_mosaic2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_mosaic2.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_mosaiced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_mosaiced.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_ok.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_plumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_plumb.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_right.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_text.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_texted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_texted.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_texts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_texts.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_undo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-hdpi/btn_ed_undo.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_arrow.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_arrowed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_arrowed.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_close.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_cut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_cut.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_cuted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_cuted.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_free.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_free.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_freed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_freed.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_left.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_level.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_level.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_mosaic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_mosaic.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_mosaic2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_mosaic2.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_mosaiced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_mosaiced.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_ok.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_plumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_plumb.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_right.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_text.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_texted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_texted.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_texts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_texts.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_undo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-mdpi/btn_ed_undo.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_arrow.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_arrowed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_arrowed.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_close.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_cut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_cut.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_cuted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_cuted.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_free.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_free.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_freed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_freed.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_left.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_level.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_level.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_mosaic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_mosaic.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_mosaic2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_mosaic2.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_mosaiced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_mosaiced.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_ok.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_plumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_plumb.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_right.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_text.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_texted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_texted.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_texts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_texts.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_undo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/btn_ed_undo.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/image_ic_adjust.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/image_ic_adjust.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xhdpi/image_ic_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xhdpi/image_ic_delete.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_arrow.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_arrowed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_arrowed.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_close.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_cut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_cut.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_cuted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_cuted.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_free.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_free.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_freed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_freed.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_left.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_level.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_level.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_mosaic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_mosaic.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_mosaic2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_mosaic2.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_mosaiced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_mosaiced.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_ok.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_plumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_plumb.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_right.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_text.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_texted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_texted.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_texts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_texts.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_undo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/btn_ed_undo.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/image_ic_adjust.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/image_ic_adjust.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxhdpi/image_ic_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxhdpi/image_ic_delete.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_arrow.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_arrowed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_arrowed.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_close.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_cut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_cut.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_cuted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_cuted.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_free.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_free.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_freed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_freed.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_left.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_level.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_level.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_mosaic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_mosaic.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_mosaic2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_mosaic2.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_mosaiced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_mosaiced.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_ok.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_plumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_plumb.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_right.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_text.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_texted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_texted.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_texts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_texts.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_undo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/btn_ed_undo.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/image_ic_adjust.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/image_ic_adjust.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/mipmap-xxxhdpi/image_ic_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/lib_edImage/src/main/res/mipmap-xxxhdpi/image_ic_delete.png
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
30 |
39 |
40 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #FFFFFF
6 | #000000
7 | #8C06FF
8 | #FF5151
9 | #199BFF
10 | #FFCC00
11 | #0078FF
12 | #14E213
13 |
14 | #ff007efa
15 | #ffffff
16 | #242425
17 | #FFF4F5F8
18 |
19 |
20 | #CDD0D6
21 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/values/image_attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/values/image_colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #FFFFFF
5 | #4CA1FB
6 |
7 |
8 |
9 | #007EFA
10 | #007EFA
11 |
12 |
13 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/values/image_dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 26dp
5 |
6 | 8dp
7 |
8 | 32dp
9 |
10 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/values/image_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 涂鸦
4 | 文字
5 | 马赛克
6 | 裁剪
7 | 还原
8 | 完成
9 | 取消
10 | 旋转
11 | 清空
12 |
13 | 请直接在图片上涂抹虚化
14 | 撤销
15 | 所有照片
16 | 原图
17 | 预览
18 |
19 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/values/image_styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
33 |
34 |
40 |
41 |
45 |
46 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 还原
3 |
--------------------------------------------------------------------------------
/lib_edImage/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
17 |
18 |
--------------------------------------------------------------------------------
/lib_edImage/src/test/java/com/zero_code/libEdImage/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.zero_code.libEdImage;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/resource/051600390884_02b7403e8a39a37fa630e48cddd9909a.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneZeroYang/EditImage/45026df43d3e9d5d9d902192122d37044dedaad5/resource/051600390884_02b7403e8a39a37fa630e48cddd9909a.jpg
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':lib_edImage'
2 | include ':app'
3 | rootProject.name = "EditImage"
--------------------------------------------------------------------------------