Compare commits
2414 Commits
6.4.1
...
dev_poyo_6
| Author | SHA1 | Date | |
|---|---|---|---|
| caf748f5f2 | |||
| 589e855aba | |||
|
|
bae13be70e | ||
|
|
cfb9cca71a | ||
|
|
50fa5831c0 | ||
|
|
33b889cb79 | ||
|
|
336b433513 | ||
|
|
211a6bd2de | ||
|
|
363f2c5ddc | ||
|
|
b3fb2ebf43 | ||
|
|
8a6f1ae9e8 | ||
|
|
af23094df7 | ||
|
|
16cb90d9bc | ||
|
|
9984adfb8e | ||
|
|
b6a5fbf313 | ||
|
|
841adbcd17 | ||
|
|
85160a305c | ||
|
|
0ea401a90e | ||
|
|
b3fc0c5ca5 | ||
|
|
5330e2d884 | ||
|
|
d2f508699c | ||
|
|
d56d9d8f45 | ||
|
|
4d3a360a09 | ||
|
|
ff9e2de819 | ||
|
|
26b6e3b83e | ||
|
|
de35a605a7 | ||
|
|
1348d2899c | ||
|
|
2ba7e9955d | ||
|
|
a27d033dc6 | ||
|
|
5573c5d96b | ||
|
|
53a6f23033 | ||
|
|
619ab8a91a | ||
|
|
ee431d0ee2 | ||
|
|
d05c975068 | ||
|
|
7746111b83 | ||
|
|
ccf6b55119 | ||
|
|
b831f20e5b | ||
|
|
39818064f6 | ||
| 97c93ea108 | |||
|
|
7b256ff3c4 | ||
|
|
17527c1b60 | ||
|
|
62c8e38a87 | ||
|
|
98f00304b9 | ||
|
|
75d87885c0 | ||
|
|
c049fcfecd | ||
| 4fd14c5cbd | |||
| 6aefceae32 | |||
|
|
7b541e8dc3 | ||
|
|
89f2f40f34 | ||
|
|
aca659efdb | ||
|
|
34ddb61aa1 | ||
|
|
d9f5c4040b | ||
|
|
4b4954483b | ||
|
|
53ea1426ad | ||
|
|
12c5e18b0c | ||
|
|
d17bb8cf50 | ||
|
|
2c0816ea28 | ||
|
|
55a769fee2 | ||
|
|
eb5d77bad0 | ||
|
|
a454da8518 | ||
|
|
95e4eca7cf | ||
|
|
c92ae05606 | ||
|
|
a038384f2c | ||
|
|
3cdf9d5609 | ||
| dc7b00c257 | |||
|
|
f75f0c0f0a | ||
|
|
fd15b269d9 | ||
|
|
2c7e499d0c | ||
|
|
71aa4d527d | ||
|
|
8a83f558e2 | ||
|
|
2fb0afef7d | ||
|
|
b415bd47ea | ||
|
|
d7982c65e1 | ||
|
|
98e9246213 | ||
|
|
c21607d6d4 | ||
|
|
7119f83cbf | ||
|
|
2b5af6a53e | ||
|
|
07ff6f32f0 | ||
|
|
d1e55f54e4 | ||
|
|
f9d0ce9411 | ||
|
|
cc67c9cacb | ||
|
|
f00dff9ca3 | ||
|
|
df5e42f2e8 | ||
|
|
101973bdff | ||
|
|
7b53729849 | ||
|
|
bc205ea9e5 | ||
|
|
3c25547f04 | ||
|
|
95128b64ea | ||
|
|
151abf13e8 | ||
|
|
fb340a152b | ||
|
|
8d0cf94d46 | ||
|
|
9e6443293d | ||
|
|
ad895b54d1 | ||
|
|
948dfe974c | ||
|
|
c202522d04 | ||
| 83e94b3b2e | |||
| a40ba0ceb1 | |||
|
|
e526964b11 | ||
|
|
381d906bdc | ||
|
|
fa4ad7f32d | ||
| e0dd0c4618 | |||
|
|
9d6c921882 | ||
|
|
6f4f5df020 | ||
|
|
e8d33e749e | ||
|
|
befc4e7833 | ||
|
|
92228b64bb | ||
|
|
096ee7ee68 | ||
|
|
82ce3a282f | ||
|
|
0799d15b2e | ||
|
|
fbcf95baeb | ||
|
|
6a78563d32 | ||
|
|
5a7950da75 | ||
|
|
25ae11b77d | ||
|
|
4bda504eba | ||
|
|
22dca86721 | ||
|
|
9e65289821 | ||
|
|
4b87df86d0 | ||
|
|
094000ce57 | ||
|
|
7ca1ee2aad | ||
|
|
a753526571 | ||
|
|
ddcb757dc7 | ||
|
|
aa0a2e38a7 | ||
|
|
a95068e7e5 | ||
|
|
c1ef54e7b1 | ||
|
|
800e1382a4 | ||
|
|
bfaa175e10 | ||
|
|
81cdd97fc4 | ||
|
|
6e0094e653 | ||
|
|
14a3eeebf2 | ||
|
|
ef09d9c58a | ||
|
|
99bc3cd71c | ||
|
|
81d390f82e | ||
|
|
4244272d00 | ||
|
|
9ab0e4ad8d | ||
|
|
684106bc59 | ||
|
|
7433369c1a | ||
|
|
9d2814c36f | ||
|
|
9475acd585 | ||
|
|
98343a2177 | ||
|
|
f60915194a | ||
|
|
6ffe601060 | ||
|
|
f52d7452f0 | ||
|
|
55bc6f917f | ||
|
|
69b868f535 | ||
|
|
6ab70b4fcb | ||
|
|
9817fb1ff7 | ||
|
|
ee8f744ed2 | ||
|
|
265e360670 | ||
|
|
4029392dad | ||
|
|
299e109c3d | ||
|
|
168d4a37b7 | ||
|
|
03a3c64a86 | ||
|
|
2e84e799d4 | ||
|
|
e69796e158 | ||
|
|
80892b14e4 | ||
|
|
9b4a2bd5e5 | ||
|
|
b300541ce9 | ||
|
|
13a373c73b | ||
|
|
6678dbb6d6 | ||
|
|
5f4bae667b | ||
|
|
b23b975edd | ||
|
|
03b05d0de0 | ||
|
|
d79dba045d | ||
|
|
0646c2c6a7 | ||
|
|
58ba80929b | ||
|
|
54eb9ea099 | ||
|
|
98cb22a706 | ||
|
|
767bc41820 | ||
|
|
ef99178d33 | ||
|
|
24fa740e05 | ||
|
|
d662d5c3ea | ||
|
|
b9a6d9b966 | ||
|
|
0586360408 | ||
|
|
9d8bef398a | ||
|
|
602417f45d | ||
|
|
86902a8f9b | ||
|
|
7cb89035d8 | ||
|
|
f39f2b483e | ||
|
|
15f19e39a7 | ||
|
|
10d1d22b8a | ||
|
|
96b302f0ee | ||
|
|
99d8df2ec3 | ||
|
|
4e42a4b04c | ||
|
|
c582376cc4 | ||
|
|
e58ce7932f | ||
|
|
cf73d3218e | ||
|
|
9a72e54ca3 | ||
| f823f17bca | |||
| d63cba7db1 | |||
|
|
6de4523d27 | ||
|
|
40966e0b33 | ||
|
|
935a5a3ec5 | ||
|
|
34aaa61f11 | ||
|
|
5373f6b5bc | ||
|
|
c84fc9e8f1 | ||
| a454a97c58 | |||
|
|
b68b334e00 | ||
|
|
bfb172c1e8 | ||
|
|
277684b8e0 | ||
|
|
0937186c93 | ||
| 11e0d62dde | |||
|
|
d181e0e743 | ||
|
|
361d23b9ef | ||
|
|
745702e36c | ||
|
|
0b62d4ddc4 | ||
|
|
23d3c9a915 | ||
|
|
8a23e76788 | ||
|
|
6f2de3a4d7 | ||
|
|
68f444b3fc | ||
|
|
f616fb1192 | ||
|
|
cd4d0c13c1 | ||
|
|
a8f92a1e38 | ||
|
|
a1b59733b3 | ||
|
|
f1670965b9 | ||
| f2ccf37022 | |||
|
|
1985eebfb1 | ||
| eb90ae9e03 | |||
| ec5f32cf1e | |||
| ec5d4d77db | |||
| 0c74d81cc6 | |||
|
|
8e860b80d4 | ||
|
|
d299e579d6 | ||
|
|
02ee96e369 | ||
|
|
ed595ec1f4 | ||
|
|
5dc2b15bd8 | ||
|
|
08bc59f80e | ||
|
|
25a926e507 | ||
|
|
abfb8e74be | ||
|
|
6e0e195c20 | ||
|
|
0854d931d4 | ||
|
|
98a0009019 | ||
|
|
b9503b91f5 | ||
|
|
dee916ea7d | ||
|
|
2e1eb3c7b4 | ||
|
|
2102a3bfc2 | ||
|
|
1576a75c08 | ||
|
|
89e4373d81 | ||
|
|
0f03a754c1 | ||
|
|
2b2fe90520 | ||
|
|
59271ce709 | ||
|
|
cbd99e0664 | ||
| 528647a0bc | |||
|
|
b4a4302cc7 | ||
|
|
09395b152e | ||
|
|
f5d8b7fed1 | ||
|
|
32257ce5a0 | ||
|
|
ca13774d87 | ||
|
|
e79741b297 | ||
| 238dfcc2d3 | |||
| 61b1101c3f | |||
| daf881f6a7 | |||
| 38f3b721e0 | |||
| 04ae7eeacc | |||
| d863c0af5a | |||
| 99c1037a15 | |||
|
|
3440b71229 | ||
| 50686957dc | |||
|
|
214e6f5d89 | ||
| 2d9e1cd685 | |||
| 60485deed5 | |||
| 7196ebd16e | |||
| 6eee7b9ede | |||
| e0405e9c13 | |||
| e8e0fc32f9 | |||
| 3d4ad99c99 | |||
| a25e22b142 | |||
| 3aeabfa32b | |||
| 47da21351e | |||
| 451a875526 | |||
| dc7b987eda | |||
| fe28d3508b | |||
|
|
cb87974320 | ||
|
|
dbd684a6e2 | ||
| abc37aa486 | |||
| 3349b2d7df | |||
| 97d636ddec | |||
| 3b8aedaa17 | |||
| 40ba4b8aa8 | |||
| f7db0b0768 | |||
| ed642f0137 | |||
| d1512bc256 | |||
| 9f90040168 | |||
| 9ae6fedd8d | |||
| 516a068c25 | |||
| 63b7a18c0b | |||
|
|
6af48002bb | ||
| 79c730c1b7 | |||
| c20a9804e9 | |||
|
|
96a6b05d03 | ||
| ba8090eec7 | |||
| e1fd4949b5 | |||
|
|
08c46a7684 | ||
|
|
3a12d848e1 | ||
|
|
cf245b0df8 | ||
| 1cde41f2d0 | |||
| 092d4cb914 | |||
|
|
0ea92c00a2 | ||
| 21ae621343 | |||
| 048c66736f | |||
| d3055d8fb2 | |||
|
|
b9164b6a08 | ||
|
|
67e5e4e02f | ||
|
|
2351618e5a | ||
|
|
b2e2ca7303 | ||
| 714e51b621 | |||
| efa4c25c4b | |||
|
|
854cad8ec6 | ||
| 46fba9429d | |||
| c67ed4b736 | |||
|
|
4a91aafb4b | ||
|
|
a0f3f246a6 | ||
|
|
2b20782def | ||
|
|
152848a04f | ||
|
|
fe827482c9 | ||
| 7fc1c2e712 | |||
| 7a6dfe5a3d | |||
|
|
96c45820b0 | ||
| ac18150503 | |||
|
|
22b208bcd9 | ||
|
|
484069dac7 | ||
| ade837e85c | |||
| 12a1f24101 | |||
| 250d4832a3 | |||
|
|
93db808f8b | ||
|
|
59f0fa4acb | ||
| 8fe6130c81 | |||
|
|
a11d7f07e9 | ||
|
|
90bc70ebf7 | ||
|
|
4618c0a4f1 | ||
| 9292e6f5c5 | |||
| 845b217c4d | |||
|
|
7edd75e223 | ||
|
|
15a52aaa62 | ||
|
|
6d6010d023 | ||
|
|
94156e2984 | ||
|
|
769f527565 | ||
|
|
eb9f615f70 | ||
|
|
3dcc801331 | ||
|
|
963fe2c110 | ||
| 9c38f40098 | |||
| 8cae89e7cd | |||
|
|
9dd3619049 | ||
|
|
96b80a460b | ||
|
|
a68bee94a9 | ||
|
|
40a2843696 | ||
| 2cefd50ac3 | |||
|
|
833b58d311 | ||
|
|
f14fb4612b | ||
| 3510a565f2 | |||
| e0669e98cf | |||
|
|
8f82c7c785 | ||
|
|
2eea1f1b75 | ||
| f1a1aae787 | |||
|
|
b68c7f1c46 | ||
|
|
dd7eb2326a | ||
| 3f1fe93f3d | |||
|
|
8c9cf4e3a8 | ||
| 0451f518d5 | |||
| a154f480f6 | |||
|
|
29badbf725 | ||
|
|
e89f22329f | ||
|
|
81e08d41af | ||
| d89b356395 | |||
| 4d2985456d | |||
| 48e3ff46ab | |||
|
|
6dd3e02c1d | ||
| d8e9cc2189 | |||
|
|
0310628ba3 | ||
| 2f54fdab12 | |||
|
|
a3228f48c2 | ||
|
|
35c83a255a | ||
|
|
0aeb2d32c2 | ||
|
|
313320473f | ||
|
|
2b86927b5b | ||
|
|
bf3ebfedbd | ||
|
|
1a2db91ceb | ||
|
|
9fa4924278 | ||
|
|
3318fa761c | ||
| a7421ba1a6 | |||
|
|
40a081caa6 | ||
|
|
1485173227 | ||
|
|
d5b60523a5 | ||
|
|
309d04653e | ||
|
|
45ae3b1624 | ||
|
|
e874c2ee16 | ||
|
|
002f0ad654 | ||
|
|
bb49472817 | ||
|
|
05e4ff89d7 | ||
| 020b5c1025 | |||
|
|
2cf10cc35a | ||
|
|
4c53c990e9 | ||
|
|
cd8b58a0ec | ||
| b41bd3b89b | |||
|
|
d66f098692 | ||
|
|
f131fcf546 | ||
|
|
eeb1cc008a | ||
| 6eba9558e1 | |||
|
|
0425b56106 | ||
|
|
c5de062171 | ||
|
|
f82dbccaa5 | ||
| 07d6b959d5 | |||
| 5ae55f87fa | |||
|
|
f59e5e527a | ||
| d70c3a8b27 | |||
|
|
c20147bf8f | ||
|
|
45743e3070 | ||
|
|
b8b43c1ef2 | ||
| 73847c46a3 | |||
|
|
b7c53a3b21 | ||
| c91947ce71 | |||
|
|
62e50ae310 | ||
|
|
5baea0f156 | ||
|
|
419e3a7ab5 | ||
|
|
66822139ba | ||
|
|
5a924d9fea | ||
| cb0772c9e3 | |||
|
|
9c9eb34756 | ||
|
|
1b57d8bc8f | ||
| edc738d80b | |||
| b5417f90b4 | |||
|
|
4bd1e4bc91 | ||
|
|
cb2729433e | ||
|
|
985e626cb5 | ||
|
|
efce2ad93c | ||
|
|
6132338c6c | ||
|
|
8c89fc1de1 | ||
|
|
a061637492 | ||
| 98095e07ee | |||
| 9764b3370e | |||
|
|
bbb5a12899 | ||
|
|
680780145c | ||
|
|
19c270ad22 | ||
|
|
ce9336737f | ||
| 0396e2d06d | |||
|
|
39cf76439f | ||
|
|
11c9a53028 | ||
|
|
c4d378daba | ||
|
|
efa698ebfa | ||
|
|
6496440e5d | ||
|
|
d3de01666c | ||
| 9621d8a6d8 | |||
| 07f97fefdb | |||
| 186b9d61ee | |||
| b7c0f5d3ec | |||
| 949c0ab759 | |||
|
|
278801b77a | ||
| 5f3ebb4235 | |||
| ab24348f72 | |||
| 022806d9da | |||
|
|
b0c5d44d1c | ||
|
|
d9b1149832 | ||
|
|
9711b1f8d4 | ||
|
|
0252963b2e | ||
|
|
ff8e75768e | ||
| c92e8dd8bc | |||
|
|
01dfb81a46 | ||
|
|
0afee3543e | ||
| 8d5990c25b | |||
|
|
d5f78cc83a | ||
|
|
cf48be7d15 | ||
| 225929c891 | |||
| bc63a3e601 | |||
| c33975fe67 | |||
| c033340aad | |||
| 24170d55e2 | |||
|
|
26a71ff825 | ||
| e36fbdc6b8 | |||
|
|
b6d0ea1fba | ||
|
|
cbf517bed6 | ||
|
|
dc0ae1124f | ||
|
|
3167ab0be8 | ||
|
|
0b218157d2 | ||
|
|
6a4ac35203 | ||
|
|
93dbee14b3 | ||
|
|
cb376aa83a | ||
| 92d1861d8f | |||
| 0ff0cb52f6 | |||
|
|
afef088555 | ||
|
|
73414f3349 | ||
|
|
abfd15f751 | ||
| 8d87dda691 | |||
| fcd13751c9 | |||
| e24805cf9b | |||
| 489a99e522 | |||
| 6a51b39134 | |||
| 86bbf6a7f3 | |||
|
|
95ded2f77c | ||
| 599e88acc6 | |||
|
|
d78055cdd9 | ||
| 2093306d36 | |||
|
|
b4adf4c77c | ||
| 8e2acc3417 | |||
| d28d0dd3d7 | |||
|
|
7d46ab8520 | ||
| 150bdba795 | |||
| 651fe12edd | |||
| d0c0f8f82e | |||
| 1f12187766 | |||
|
|
754f2a9294 | ||
|
|
9320d6c209 | ||
| 1c9493d7c8 | |||
| 34e4765e13 | |||
| d4d191fad6 | |||
|
|
8228c45a4d | ||
|
|
4147e3c5f5 | ||
|
|
583740e866 | ||
|
|
0db8eefbe6 | ||
|
|
3f68e2a3aa | ||
|
|
11ba2c45f8 | ||
|
|
320584769d | ||
|
|
5922f4c08b | ||
|
|
b29b0a1688 | ||
|
|
f88356cea2 | ||
|
|
2a67cf7228 | ||
|
|
a100ab1a4a | ||
|
|
69b45f1d21 | ||
|
|
479a743d29 | ||
|
|
382c53ab1f | ||
|
|
1c22f5fd48 | ||
|
|
09bef7afa6 | ||
|
|
88b96267ef | ||
|
|
7c006e8e03 | ||
|
|
f35b547c0d | ||
|
|
490c558e03 | ||
|
|
bbf5d159b4 | ||
|
|
e982994ecd | ||
|
|
a0294a8405 | ||
|
|
756cbb1ce1 | ||
| 9e5427bd35 | |||
|
|
f626ab03d4 | ||
|
|
0d7bdce4f0 | ||
|
|
cd3feebb94 | ||
|
|
3cca1a9e54 | ||
|
|
0b7b959151 | ||
| 1f1ac71bb0 | |||
|
|
ce7b6decc1 | ||
|
|
4a4a52aa61 | ||
|
|
123b9dd74a | ||
|
|
28dba93f17 | ||
|
|
285515345b | ||
|
|
f24744afe8 | ||
|
|
1e466ac13d | ||
|
|
d37b490088 | ||
|
|
a61bc8fbb8 | ||
| 9db23a32d1 | |||
|
|
5f1eadc47b | ||
|
|
de11b5123d | ||
|
|
5b0f5f03ab | ||
|
|
6095d2d04a | ||
|
|
3953e146a5 | ||
|
|
f04a2865af | ||
|
|
f94b3f27e3 | ||
|
|
61a966ea41 | ||
|
|
d0f2ac2c60 | ||
|
|
5dff64ec99 | ||
|
|
cad8236e5c | ||
|
|
faa401245f | ||
|
|
4fc021e866 | ||
|
|
f9a21d0357 | ||
|
|
d72a9a39c6 | ||
|
|
0317b339f8 | ||
|
|
4fabf3aba3 | ||
|
|
4693954a72 | ||
|
|
859810f1f6 | ||
|
|
53f389ddc8 | ||
|
|
ddc9bc344e | ||
|
|
cf34e73d32 | ||
|
|
1981fb553a | ||
|
|
3b6d586b58 | ||
|
|
50b6deaf01 | ||
|
|
bc8d916445 | ||
|
|
6870037683 | ||
|
|
8af7f907eb | ||
| 4d96bcc667 | |||
| f7845dde6f | |||
| ae9ef1f8a1 | |||
|
|
1023c0ab4d | ||
|
|
8184cf6c7f | ||
| df735af252 | |||
|
|
6f71a825b5 | ||
|
|
08e009e5f9 | ||
|
|
1a4a0632ee | ||
|
|
b3a02f8c2c | ||
| aa9bc7326c | |||
| 22769b981d | |||
|
|
85b4facfe8 | ||
| aef0435b93 | |||
| 9cc30186cd | |||
| f99641ed35 | |||
|
|
0552f56eb4 | ||
|
|
7ab4081f0b | ||
|
|
e7ef492015 | ||
| 1aa6cb8f55 | |||
| dc87fc7048 | |||
|
|
04b70d910a | ||
| a4ce44d9ba | |||
| 469e3e30ad | |||
|
|
7e7616ef29 | ||
|
|
dd64568fdf | ||
| 50fb801cf7 | |||
| e0200a9c7f | |||
| 5a32047c6d | |||
|
|
45fd56ba66 | ||
|
|
30b2884c46 | ||
| 0c07e8c2be | |||
|
|
508e9f1931 | ||
| 78d870ed89 | |||
|
|
c00afb1db0 | ||
|
|
dfca615735 | ||
|
|
a920b61bc4 | ||
|
|
3effb630c5 | ||
| 0e596e9be9 | |||
|
|
0a70cc027f | ||
| 47077a465a | |||
|
|
aa62dda844 | ||
|
|
004a5b2a53 | ||
|
|
64f9cee3af | ||
| 1eb43fb8cf | |||
|
|
f770370be0 | ||
| e185eb8612 | |||
| 299add0575 | |||
| feb08e1759 | |||
| 16755a9c8c | |||
|
|
d6e6164549 | ||
| 52c561fa08 | |||
| c2979b4cf7 | |||
|
|
0f70f10aed | ||
| 45f471055e | |||
|
|
c49c9c2f81 | ||
|
|
74b19de11c | ||
|
|
00b89aab69 | ||
|
|
6ff6cbbe6b | ||
|
|
65d38de73c | ||
|
|
ae6fdab7e8 | ||
|
|
3d1c4466e0 | ||
|
|
9963b37b6f | ||
| a8a1aa2e71 | |||
| 2857127285 | |||
|
|
3a1268aac7 | ||
|
|
5b813aff88 | ||
|
|
d9951b5a35 | ||
|
|
f928fce069 | ||
|
|
d365389ff8 | ||
| a4e98f3703 | |||
|
|
a307e6f864 | ||
|
|
b5c8f14994 | ||
|
|
34323fd983 | ||
|
|
1f7c6c8adc | ||
|
|
29c2334ee0 | ||
|
|
2aa50ecfc7 | ||
|
|
58b2d69601 | ||
|
|
e061e61088 | ||
|
|
24788d7e21 | ||
| 54693c0d37 | |||
|
|
27f136d6ca | ||
|
|
92d271ff93 | ||
|
|
0b15df41b8 | ||
|
|
f22f8fcb4b | ||
|
|
7627219e77 | ||
|
|
cf749d85c6 | ||
|
|
ac6eb21e06 | ||
|
|
5ca13b770c | ||
| 7795317c14 | |||
|
|
a036e5eff6 | ||
| c6fb323c68 | |||
|
|
926a1a3cb6 | ||
| d629ee3f9f | |||
| df0d9795ed | |||
| 1759757176 | |||
|
|
661c2fd334 | ||
| b175e42ee1 | |||
| 6cdc648ea9 | |||
|
|
85ccbcccae | ||
| 0a6b210a76 | |||
| 43d1abbae0 | |||
| 4a5e581978 | |||
| 8a7b65955c | |||
|
|
3445ee2a56 | ||
| cf2274195f | |||
|
|
aad607ace8 | ||
| 17506f6cbf | |||
|
|
418073f07e | ||
|
|
319295de57 | ||
|
|
dcf3f5c308 | ||
| 30bdf83724 | |||
| fbb801bf62 | |||
|
|
44601c74b4 | ||
| 2808e41288 | |||
| 05aea2448f | |||
| 34986d6897 | |||
| 924afce81e | |||
| 48dcfd4a04 | |||
|
|
163ab1c80d | ||
| e06f944def | |||
|
|
a5d546d1d1 | ||
| 1304ec6cde | |||
|
|
f46d14ce28 | ||
| e2005582fe | |||
| a56a5849fe | |||
|
|
1495bfee99 | ||
| 19eecd7022 | |||
|
|
d415efde35 | ||
| 61ee585ae9 | |||
|
|
7b103aaf7c | ||
|
|
9eba98f709 | ||
| dea3264577 | |||
|
|
42cfcce1dc | ||
|
|
f697e650a8 | ||
|
|
ac78268a85 | ||
|
|
9d543f2211 | ||
| d001712067 | |||
|
|
dc28a3d81e | ||
| 728dec9d97 | |||
|
|
f65c698602 | ||
|
|
215a2f8927 | ||
|
|
a21352302b | ||
|
|
0b3ebdfc30 | ||
|
|
f10657f89c | ||
|
|
0dc1009661 | ||
|
|
302b789970 | ||
|
|
bd9c8c2265 | ||
| 58ace7d613 | |||
|
|
c723e14182 | ||
|
|
3982afb0d3 | ||
|
|
280920d5f0 | ||
|
|
e25980cec8 | ||
|
|
e353638ec1 | ||
|
|
65a3a64d7d | ||
| b10312118b | |||
|
|
419b5d08b4 | ||
|
|
b146f93029 | ||
|
|
ef34a6cf4f | ||
|
|
213319d5d3 | ||
|
|
ddb4e98afd | ||
|
|
8dbc0dad7a | ||
| cdf3c4e411 | |||
|
|
446dc271d6 | ||
|
|
ecca9b7b8b | ||
|
|
331b55a5ab | ||
|
|
f8ac4617ed | ||
|
|
d0b7b065b2 | ||
| 53e6cb5a70 | |||
|
|
ad79190a61 | ||
|
|
5895fa8d71 | ||
|
|
48886374d5 | ||
|
|
32d0fe497d | ||
|
|
6347473d0c | ||
| 6df819f3b1 | |||
| 39fbe90e8b | |||
|
|
3396ca63d0 | ||
| 8c5ae3b61a | |||
|
|
484891cfe7 | ||
|
|
5c00e065d2 | ||
|
|
2857bb09a2 | ||
|
|
79c1c01003 | ||
| a2864187ed | |||
| ef76b2c7e4 | |||
|
|
05e7c4ffdd | ||
|
|
b4b1efe730 | ||
| 0c7ae4e4f7 | |||
|
|
b35d5d242e | ||
| b8264997f4 | |||
|
|
2ab1b31a94 | ||
|
|
9dba41c22f | ||
|
|
f1645cf72c | ||
|
|
cd35b9e40f | ||
|
|
33bce43737 | ||
|
|
1f8025599b | ||
|
|
7c44f09803 | ||
|
|
0b89ac21e8 | ||
|
|
238181deca | ||
|
|
71a7b47d42 | ||
|
|
59446d2518 | ||
|
|
8a8a7a8326 | ||
|
|
089b1881f1 | ||
|
|
7b1f3ddd79 | ||
|
|
56ae033523 | ||
|
|
f772a64507 | ||
|
|
8c75317ddc | ||
|
|
256c19a09e | ||
|
|
82c1d15ca5 | ||
|
|
aff5a178a0 | ||
|
|
04b1764f7b | ||
|
|
076f7130c8 | ||
|
|
b7842d5ac9 | ||
|
|
eb5aebda51 | ||
|
|
6990bd13ed | ||
|
|
c18af48fbb | ||
|
|
68e6f5df1b | ||
|
|
dc46ffc5b6 | ||
|
|
c58a5a9a55 | ||
|
|
e2ee742091 | ||
|
|
bcc86a899c | ||
|
|
b60031d2d0 | ||
|
|
54aa5fee67 | ||
|
|
816fd21fbc | ||
|
|
92e6b563e4 | ||
|
|
d7bc2615d6 | ||
|
|
21473b1d69 | ||
|
|
9bdee649d8 | ||
|
|
f1a8cd3a68 | ||
|
|
a39005b1a9 | ||
|
|
ec1197e5da | ||
|
|
45372f37b8 | ||
|
|
df93b9495a | ||
|
|
86d730cdf1 | ||
|
|
f356446c03 | ||
|
|
bf7bc6b786 | ||
|
|
6a3c15e3e7 | ||
|
|
07d3b190e2 | ||
|
|
27b316d39b | ||
|
|
f928fcd4bc | ||
|
|
adcafc7e16 | ||
|
|
b191dfb1be | ||
|
|
192b0cb417 | ||
|
|
a2435cbe95 | ||
|
|
8925d478da | ||
|
|
926de0463c | ||
|
|
993b09b853 | ||
|
|
e6c8495158 | ||
|
|
e15953dc64 | ||
|
|
4ff529ace9 | ||
|
|
530622c72c | ||
|
|
7f38739ddc | ||
|
|
bc549d52f6 | ||
|
|
14f0de093e | ||
|
|
51457738d2 | ||
|
|
d8a0427791 | ||
|
|
8abf92d42c | ||
|
|
fc2d700a31 | ||
|
|
867029fa3a | ||
|
|
52e199b901 | ||
|
|
c5d537fb4d | ||
|
|
e081f1e058 | ||
|
|
7bedf93dd5 | ||
|
|
000929fd02 | ||
|
|
3e5ba2ba19 | ||
|
|
a25ce2034f | ||
|
|
1625135d0c | ||
|
|
add3589683 | ||
|
|
45a5d6ad61 | ||
|
|
7b62409bf1 | ||
|
|
45ad8a9810 | ||
|
|
a788c347de | ||
|
|
c3d4cb8d62 | ||
|
|
916a1447f0 | ||
|
|
b2ee091c03 | ||
|
|
cf169e9a4e | ||
|
|
ea0ff70595 | ||
|
|
ce37918745 | ||
|
|
260b615d2b | ||
|
|
45566001a7 | ||
|
|
12482b6624 | ||
|
|
2d7684a5c8 | ||
|
|
c1d6b67322 | ||
|
|
69c0d5f28a | ||
|
|
d541a4d506 | ||
|
|
4b46c72f5a | ||
|
|
e191fb82a3 | ||
|
|
32ebfa719d | ||
|
|
c94f549531 | ||
|
|
6d98afa319 | ||
| 20ccb37ccf | |||
|
|
79fa6be313 | ||
|
|
210e755fed | ||
| a6faf12ff6 | |||
|
|
e2148c3f31 | ||
|
|
869ca75464 | ||
|
|
ce48a7dcf0 | ||
|
|
866024ae95 | ||
| b40abb9bc0 | |||
|
|
37217e529e | ||
|
|
eedbbb5304 | ||
| 4b3b47b65f | |||
| c015459cf1 | |||
| 326ced4646 | |||
| 18970c22cf | |||
| 00db8a00c7 | |||
|
|
0756dd9560 | ||
| f3195bbcf8 | |||
| 4e4b5f90bb | |||
| 3150489384 | |||
| 9ff382e35b | |||
| bcd8f7af52 | |||
| 3595b89672 | |||
| 6e8842d30d | |||
| 7b5cd9b797 | |||
| 9ec241f2a3 | |||
| a876018b0a | |||
| ea397af123 | |||
| a475e5dc2f | |||
| 54258c3f13 | |||
| d383a08013 | |||
|
|
fed6289f67 | ||
|
|
9b301eba25 | ||
| d1edf6bdd8 | |||
|
|
7ca8694aed | ||
|
|
406c67bf3a | ||
|
|
d643df72bc | ||
| a3dacf1f59 | |||
| 37605f46b7 | |||
|
|
a4895df622 | ||
| fc63cbbf50 | |||
| b7ba717cb9 | |||
| 0c5ef0befe | |||
|
|
84d4423069 | ||
|
|
0721ff4f37 | ||
| a5b0ee757c | |||
|
|
82fd35305a | ||
| e89e82483b | |||
| 57bda40a82 | |||
|
|
93aa8e55e5 | ||
| 2e907bc1ed | |||
| 8d984951c3 | |||
|
|
dd6600a89e | ||
|
|
233469c7e4 | ||
| 357ece2ebe | |||
|
|
72e9633045 | ||
|
|
7a31ca52da | ||
|
|
33930f3e32 | ||
| 8e19ddcc99 | |||
|
|
1a58311e26 | ||
| 9360e5438c | |||
| fa8d8a7421 | |||
|
|
bebf0820ca | ||
| e1f4e8dde4 | |||
| 2b59b1b4fe | |||
| cee1476ab1 | |||
| 20a6bae5ff | |||
| b6732adfd2 | |||
| bec031688e | |||
| 7f11195ede | |||
| d4ff9c3072 | |||
| 0a442e7df9 | |||
| 52f1a78e36 | |||
|
|
6bcaf2ba9c | ||
|
|
75b176a81e | ||
|
|
3de972d12c | ||
|
|
95252f2f02 | ||
|
|
3b351ffad8 | ||
| 2332255b37 | |||
|
|
90c2f3e2da | ||
|
|
644615ffc0 | ||
|
|
345c9067aa | ||
|
|
c20312b982 | ||
|
|
643568f63b | ||
|
|
f03ba293b5 | ||
| a2f954b28a | |||
| d4549793d1 | |||
|
|
5da8855948 | ||
|
|
348dca8474 | ||
|
|
5afed0ee43 | ||
|
|
d065726274 | ||
|
|
8f9d558043 | ||
| c594364574 | |||
|
|
68140c8a3a | ||
| 5a4001c858 | |||
|
|
d5953bd651 | ||
|
|
17a2f5e091 | ||
|
|
b2297b062e | ||
| b53472de28 | |||
|
|
9bce235817 | ||
|
|
60ce5572cf | ||
|
|
3761cad653 | ||
|
|
2a276503b5 | ||
| fd0ad36a58 | |||
| 41c8783b53 | |||
|
|
7226add482 | ||
| 09e5f9b984 | |||
| 83ee1f94df | |||
|
|
7e1b054a98 | ||
|
|
9e0c437af5 | ||
|
|
ad26ae7db8 | ||
|
|
84230e517e | ||
| 9818a1af74 | |||
| f91ba79c5c | |||
|
|
0ea9ffc2e8 | ||
|
|
defb5fdd02 | ||
| b443fdd683 | |||
|
|
c11c66f56f | ||
|
|
a618bee6b7 | ||
| 399bedb874 | |||
|
|
3b6e2d47f4 | ||
|
|
96daf73a5c | ||
|
|
55cbd0ff5b | ||
|
|
a3ab9ff03e | ||
|
|
92ed82ea2a | ||
|
|
6d262d0c94 | ||
|
|
ce1174a88c | ||
|
|
2406e9bede | ||
| 9b3a011499 | |||
|
|
7859e7cb29 | ||
|
|
1fd36e3ba0 | ||
| ec3722b7d0 | |||
|
|
35917a5848 | ||
|
|
7ea6bb570d | ||
|
|
43f95260e6 | ||
|
|
54a4c0b590 | ||
|
|
2057a3575f | ||
|
|
aa809ebaf4 | ||
|
|
dffa71e346 | ||
|
|
fea46aab1f | ||
|
|
e032e0807b | ||
|
|
24ed313f60 | ||
|
|
02b70d559d | ||
|
|
7a26e81f67 | ||
| d07439efcf | |||
|
|
7bca817633 | ||
|
|
bad2b3689a | ||
| 3cc9b90151 | |||
|
|
e32e6f95b0 | ||
|
|
2162645da1 | ||
|
|
af17c85366 | ||
|
|
20c00e2896 | ||
|
|
44b95cb1c6 | ||
| 40e744a533 | |||
|
|
82ccd2d89c | ||
|
|
994bd2a3aa | ||
| 3ab91a74d1 | |||
|
|
d899975495 | ||
| dbbe753492 | |||
|
|
017320ac09 | ||
| 7ce0bb3a7c | |||
|
|
a78d5b4aba | ||
| 37fd1e9f47 | |||
|
|
97ad28ba62 | ||
| 3304e8f673 | |||
| e7daabe588 | |||
| d912ad6119 | |||
|
|
dfeb1c246b | ||
|
|
9588619b73 | ||
|
|
6ba71508ca | ||
| c8f443c105 | |||
|
|
ebcfddf450 | ||
| e43fb5e479 | |||
|
|
0c096dcafc | ||
|
|
545c69ff8b | ||
| bf8d88608d | |||
|
|
45c256cbbb | ||
|
|
fb1d6c0688 | ||
| fe921e25bb | |||
|
|
d5ca010ec7 | ||
|
|
04259472a1 | ||
|
|
d6032a0a0a | ||
|
|
4a7790d968 | ||
|
|
49810407ce | ||
|
|
fa086dc5cb | ||
|
|
3f8d6ed4af | ||
|
|
986902886a | ||
|
|
8ed7595aec | ||
|
|
b78fef6adc | ||
| fae0d01dc2 | |||
| 9a8bc0505d | |||
| e31fa0310c | |||
| 2705342e18 | |||
| 1bdf3a2ba3 | |||
|
|
5afa3bd30b | ||
|
|
54458bd0c0 | ||
| c53b9a6064 | |||
| 92d4130c45 | |||
|
|
a353e51ba8 | ||
|
|
0646f245b6 | ||
| 7e3ca79a01 | |||
| dfeb3a78c1 | |||
| e32d450ca1 | |||
| f29766731c | |||
| 736592b4e1 | |||
| 3108c898c2 | |||
| dd2f3db16a | |||
| 8af231e526 | |||
| fdbbc3b224 | |||
| 1e4b0bb536 | |||
| 4729f93515 | |||
|
|
3376a57f9d | ||
|
|
410fcb5895 | ||
|
|
9b62ab6011 | ||
|
|
62aa1d63df | ||
|
|
034f2dba5d | ||
|
|
aee1d6cad4 | ||
| 9b01ae4d82 | |||
| 16f23519b1 | |||
| 9bfed0bc7b | |||
|
|
bc0ed26377 | ||
|
|
0d14ce5aee | ||
|
|
4a7423a5b9 | ||
|
|
0a4425d705 | ||
| d4c2ef71cb | |||
|
|
7184b147d9 | ||
| 39e9670cff | |||
|
|
7d7535935a | ||
|
|
dd657e9918 | ||
| 09cef4ade6 | |||
| 7038681f8c | |||
| 6cf68838f8 | |||
| c3a08974d1 | |||
|
|
20c25a51ef | ||
|
|
9dfb772224 | ||
|
|
f5f68f16b7 | ||
|
|
7672cea263 | ||
| 0a02b39c12 | |||
|
|
e786ae16c2 | ||
|
|
1d447b0a90 | ||
|
|
4918f9ba20 | ||
|
|
124b18dcb0 | ||
|
|
f55e9c0cfe | ||
|
|
84c43f74bc | ||
|
|
674346b6de | ||
|
|
64f40d52da | ||
|
|
75e342975c | ||
|
|
dd4172fc3d | ||
| 6b7a98dbc3 | |||
| 640dea5c53 | |||
| a907897239 | |||
| 3807ff8916 | |||
| 36b85c15f5 | |||
| 3e91068866 | |||
|
|
4d61c7e176 | ||
|
|
c6d9dbc118 | ||
| 6743ec3cf6 | |||
|
|
addab80997 | ||
|
|
9081ba4cd6 | ||
|
|
12bedd630e | ||
|
|
003c7f9e12 | ||
|
|
9089e96856 | ||
| 60c14f720d | |||
|
|
c139b03417 | ||
| b3fb6e62ae | |||
| 613185db40 | |||
|
|
291492f2d0 | ||
|
|
cbe91c84e9 | ||
| f417e4ead8 | |||
|
|
08bc6d554a | ||
|
|
895a1c6951 | ||
| b9f1474362 | |||
|
|
58508ca0ae | ||
|
|
5736265388 | ||
|
|
e68d20252a | ||
| 44b4b06592 | |||
| fb7551f7d0 | |||
|
|
40455fffc9 | ||
| 195035c456 | |||
| 492003ff01 | |||
| 17c2e7f795 | |||
| 1a3d66553c | |||
| 710cddd3a7 | |||
| da7ebb2663 | |||
| 6a6696f355 | |||
| 368b002db6 | |||
| 501a7b482b | |||
|
|
279575d80b | ||
| 3bf594d0b5 | |||
| 5f33fa38f6 | |||
| e0312eedd1 | |||
| 69d8feb9a9 | |||
| 500588c842 | |||
| 0a70da82f0 | |||
| abbb8c524c | |||
| 1334d173cf | |||
| f3ff37aea7 | |||
| 9741be743c | |||
| f54054283c | |||
| fd06243c22 | |||
| cef94a248e | |||
| beb566b294 | |||
|
|
6889828c00 | ||
| 9c57f0bd96 | |||
| a1c96cfd0f | |||
|
|
1198a8f1d8 | ||
| a255d1f2b5 | |||
| 53ce1c703e | |||
| 3f9e95ce7d | |||
|
|
8e07d4523f | ||
| 29ddc54303 | |||
| ae9c050ae6 | |||
| 7b61e8c562 | |||
|
|
23a396864f | ||
| af8052f65b | |||
| 6603a2dbb5 | |||
| f3a0b4d145 | |||
| 0c99324904 | |||
| 8d077e8062 | |||
|
|
3aaafdbbbe | ||
|
|
f4016089a1 | ||
| c53757c64b | |||
| c8c4352284 | |||
|
|
cd2e176f0a | ||
| e6d92ffc86 | |||
| ea0a3375e4 | |||
|
|
06357088c1 | ||
|
|
fa24d226ee | ||
|
|
7eb8153744 | ||
|
|
35f16bdcae | ||
|
|
aacd8b8735 | ||
| 9926997fd7 | |||
| b02cbd7831 | |||
|
|
4150eeed64 | ||
|
|
6e595ff1e4 | ||
|
|
fbc50229e8 | ||
| 1edb07d76c | |||
| 9641d90f32 | |||
| 3095438a5c | |||
|
|
067bbc70c5 | ||
| 7201fd37f3 | |||
|
|
0bab58d507 | ||
|
|
f1ac21fe87 | ||
|
|
f4b5cdfed3 | ||
| 9021659770 | |||
| e04d277560 | |||
|
|
a7a9a28c09 | ||
|
|
bbd394044f | ||
|
|
49df393781 | ||
|
|
f0a8c17401 | ||
| a01ddd310b | |||
|
|
26ec74932f | ||
|
|
3aa85ca9bb | ||
|
|
a67c2b4009 | ||
| 9486a1a572 | |||
| c1aa8188ce | |||
|
|
a83e3e0511 | ||
|
|
3488da27f0 | ||
| 56845de59d | |||
|
|
282790ead5 | ||
|
|
db165cc05d | ||
| 49313ca326 | |||
|
|
b0008405e2 | ||
|
|
9c32c6af25 | ||
| baa2ec127f | |||
|
|
c3b5f17f44 | ||
|
|
c28a91b128 | ||
|
|
f064864d76 | ||
|
|
66290323d8 | ||
| 9526a14ca2 | |||
| 27715cda2c | |||
| 65bfc77376 | |||
| 99618a2779 | |||
| 1b637b7a77 | |||
| 6ee678bd74 | |||
|
|
b4dc035a1b | ||
|
|
1f7aef91a8 | ||
|
|
3e72b4a9eb | ||
|
|
4f103dadc9 | ||
|
|
055d002a34 | ||
|
|
426f7450a2 | ||
| 73a71dabc6 | |||
| 435dc1c4fb | |||
|
|
f347d283a0 | ||
| a6754eb503 | |||
| 070312ff53 | |||
| bd8cf94171 | |||
| 98bb182d56 | |||
| 3454b6f924 | |||
| 5af061c26f | |||
| 83a240fcb8 | |||
| 17decb63fa | |||
|
|
dbe861c608 | ||
| c1c8921f59 | |||
| 82b3b23470 | |||
|
|
e28c6228ad | ||
| df0f5f31e0 | |||
|
|
2a6af7c165 | ||
|
|
8611817a6a | ||
|
|
e4c48f948d | ||
| 46e37b14e4 | |||
| 0d86d142c9 | |||
|
|
96cbadac2c | ||
|
|
f8356b1283 | ||
|
|
576d39461a | ||
|
|
8410439a90 | ||
|
|
73b075b2a7 | ||
| a6b5c102d2 | |||
|
|
229c8e72cf | ||
|
|
f99bef4ac8 | ||
| 34c569ecb5 | |||
| a041450766 | |||
| b5673025be | |||
| f0ddd98942 | |||
| e9488df780 | |||
|
|
e67287e7d3 | ||
|
|
4b8dd546ce | ||
|
|
319a23bf2d | ||
| 611f1da9b8 | |||
| 1953b5a776 | |||
|
|
43deb95435 | ||
| 5a9535e81d | |||
|
|
097528f97a | ||
| abe71808fb | |||
| 59508a45cb | |||
|
|
11bc23418e | ||
|
|
5a5164f72b | ||
|
|
381ca84525 | ||
| 79a709a76f | |||
|
|
5dcdd3fc5f | ||
| 1dce512d27 | |||
| 840129651d | |||
| 59c19d996e | |||
| 703bafa013 | |||
|
|
9e6e25fb9e | ||
| bddf8c71ae | |||
| 47c3282861 | |||
| 181ff4274c | |||
|
|
dc5633bcb9 | ||
| 369f3f2cae | |||
|
|
293c9dcf9e | ||
|
|
d0e2278df7 | ||
| f913248fa1 | |||
|
|
098ef7aa36 | ||
|
|
bfbbe54308 | ||
|
|
32e3584fef | ||
|
|
90c7483dbc | ||
|
|
e38262826d | ||
|
|
cbb1531356 | ||
|
|
0ed37aee11 | ||
|
|
c23ed7defb | ||
|
|
06e077146b | ||
| 10588e4810 | |||
| 4b7469d9d4 | |||
|
|
eb21a17475 | ||
|
|
974546697b | ||
|
|
8507fc1bb7 | ||
|
|
bb4f8bb98e | ||
| 4a4cc179bf | |||
|
|
db8dc2a781 | ||
|
|
4ae1b12be0 | ||
|
|
06289b44d9 | ||
|
|
32fa77be39 | ||
|
|
9869a2376c | ||
| af4176bcb7 | |||
| 499b73295d | |||
| bec764a329 | |||
| 58c988a83a | |||
|
|
0506d82165 | ||
| cfc72f7441 | |||
|
|
b305ba925b | ||
| e99b18eec6 | |||
|
|
38b080f082 | ||
|
|
605f10d0ac | ||
|
|
f7480c6e43 | ||
| ceef0f1e57 | |||
|
|
19c0c8c6e7 | ||
| d50c56bbb2 | |||
| 8ce65ced30 | |||
|
|
80e93f9981 | ||
| a34e90753c | |||
| a53da7a2b8 | |||
|
|
bdd6124300 | ||
| 47c3f59f74 | |||
| 76f94895fe | |||
| e0eea59539 | |||
|
|
917d237b6d | ||
| 508f1a52ae | |||
|
|
4429dc7a4c | ||
|
|
296a6d24bb | ||
|
|
6c19f0efc4 | ||
|
|
6f7a9a9310 | ||
| 66e011f2d3 | |||
|
|
9e7909ec70 | ||
|
|
8ae58e9c14 | ||
|
|
2ce527cee8 | ||
|
|
28ef982b74 | ||
| b44524b25f | |||
| f76d649233 | |||
| 90fee86c19 | |||
| 9707898af9 | |||
|
|
9c3fbe0506 | ||
| a8178c51a0 | |||
|
|
2b62d018b5 | ||
|
|
f7cf72f15f | ||
|
|
b3d4d2b8f9 | ||
|
|
8cbbd4015f | ||
| 51bf55fdeb | |||
|
|
18a5f46133 | ||
| f201e0978e | |||
|
|
63c2891650 | ||
| af164f549f | |||
| 33034ce4d6 | |||
|
|
9d38ff7c8f | ||
| 16caf60f77 | |||
| f3bca96ee8 | |||
|
|
b0ed276e23 | ||
| 906ff6cfa6 | |||
| 6427311cec | |||
| 181f081706 | |||
| 14490cacfa | |||
| 6ff83dabff | |||
| a6d81ef666 | |||
| 11679a62a0 | |||
| 36410ddcaa | |||
|
|
3bf6518e25 | ||
|
|
028f2794bf | ||
|
|
1c198a44cf | ||
| 1fba3bd53e | |||
| fd15428ed9 | |||
|
|
a5fd14cc0e | ||
|
|
3c7a2d3964 | ||
|
|
325d7254f0 | ||
|
|
153d5ff159 | ||
| a86cf97d74 | |||
| 192587f758 | |||
|
|
5697a19f91 | ||
|
|
1fa1874241 | ||
| c43b581157 | |||
| ba5a80fb1d | |||
| 73c8db8fb4 | |||
|
|
f55e1b9c05 | ||
|
|
e5a07613aa | ||
| ed46eb30a8 | |||
|
|
971fceebcd | ||
|
|
329bd63229 | ||
|
|
d320373b07 | ||
| 326bb5ae7f | |||
|
|
95c39cca9d | ||
|
|
849677e50e | ||
| c4ae047a4b | |||
| 5657d5a00b | |||
| 4b6b477351 | |||
| d035018ada | |||
| e301e7bfce | |||
| 97ad5c2d92 | |||
| 43e7713f6b | |||
|
|
cfce501d45 | ||
|
|
b2f35fdc16 | ||
| 87afe9297d | |||
| 48f1d42739 | |||
| 9eed92302d | |||
|
|
f12f6a9130 | ||
| ef757a8adc | |||
| 0177a1314d | |||
| 26cb58463a | |||
|
|
d1d8054c01 | ||
|
|
2db89365bb | ||
|
|
87ba382e81 | ||
|
|
55290a71aa | ||
|
|
5095de3c43 | ||
|
|
70a91fedf3 | ||
| ef8f87d100 | |||
| 6d83c6f8ae | |||
| ce2048b9a5 | |||
| c22da60b82 | |||
| c78bb79633 | |||
| 3a980d22fd | |||
| 2b56eff39a | |||
|
|
9472ccf6c8 | ||
|
|
59d384a81c | ||
|
|
c02f24fdcd | ||
|
|
86c5334ab4 | ||
| 6ef8c3778b | |||
| 0c6eac2936 | |||
|
|
62e2b93bd5 | ||
|
|
d80bc3bd27 | ||
|
|
085f19c3ca | ||
| f4d23c57df | |||
|
|
95429402c7 | ||
|
|
1da79d6f48 | ||
|
|
926bd1a22e | ||
|
|
554bfa137a | ||
| 9e5a61f66c | |||
|
|
be608fd90b | ||
| c9e53b4dfd | |||
| c2aba5da4b | |||
|
|
420118b652 | ||
|
|
076008ce89 | ||
|
|
8455d1253c | ||
| 07f8f46f1f | |||
|
|
8b46c57482 | ||
|
|
db834caf00 | ||
| 5c1eef1419 | |||
| fe29d307a9 | |||
|
|
b8fea6366c | ||
| 06dddb5273 | |||
| d774296db9 | |||
|
|
077cc7fd80 | ||
|
|
fdf9d0aea2 | ||
| 92c38dc0dc | |||
|
|
d8c4b9dd04 | ||
|
|
342b2e9139 | ||
| 88ea48b6ca | |||
|
|
0726c5dc1c | ||
|
|
046adc9340 | ||
|
|
46fa2419d3 | ||
|
|
5c5114f808 | ||
|
|
7f2f7ea4d8 | ||
| a89c441555 | |||
| a1762bc791 | |||
| 34432e5ccf | |||
|
|
46f20c9663 | ||
|
|
e0753ebb29 | ||
|
|
d7d24904bf | ||
|
|
abbc2fc4ee | ||
| 07f0f39978 | |||
| 8d932a09e1 | |||
|
|
34c855fc8f | ||
|
|
824d431a63 | ||
| af63c4c8ac | |||
|
|
16ba71493e | ||
| 94f8ee7f3b | |||
| e7c97f2b55 | |||
|
|
a7e6efa0dc | ||
|
|
ea9807dcdc | ||
| fdd30aa52a | |||
|
|
ba23f720eb | ||
| 05ede89cba | |||
| d6eddeb130 | |||
| bf4710470f | |||
| 5d2a246916 | |||
| cca8f43f61 | |||
|
|
1d66a9b7fb | ||
|
|
c1c4a7a38b | ||
|
|
b8a91a85e4 | ||
|
|
7cb7258210 | ||
|
|
8d823f7a07 | ||
| 6d458d0c7f | |||
| eaed7e448b | |||
| b2f779f58a | |||
| 79ded6bff4 | |||
|
|
d86e16c9f5 | ||
| f2cff3b93f | |||
|
|
e97a4e607c | ||
| 4d86317ec8 | |||
| d36ece4c54 | |||
| 11cf971514 | |||
| 60da453114 | |||
|
|
3d5ac05d36 | ||
| a50a7140fd | |||
|
|
d3268e57bc | ||
|
|
3549c25cca | ||
|
|
859f54b1e1 | ||
| 15b232f52a | |||
| 3c80038bef | |||
| a808cd13c0 | |||
| ce8088059a | |||
|
|
cd0067d77b | ||
|
|
894e264fb3 | ||
| 5dd5b2e0ea | |||
| d14939c893 | |||
|
|
8f58c485c8 | ||
|
|
11e809a978 | ||
|
|
20aa6002f8 | ||
|
|
ffcb0e8790 | ||
|
|
3de7160538 | ||
|
|
1e595ec526 | ||
| 344bbcdfc8 | |||
| c1aeaa0e1b | |||
| e108494bd5 | |||
| bc0e698a77 | |||
| b82c87d5d6 | |||
| 80fe5271f6 | |||
| 944d703e36 | |||
| 911869ed9f | |||
| 543336af99 | |||
| 5d7cff6707 | |||
| 1bbab7ac9e | |||
|
|
16592aaecb | ||
|
|
3de9ff57c3 | ||
| e932238fc2 | |||
|
|
df436bbe1e | ||
|
|
49bd97f646 | ||
| 731f941298 | |||
|
|
c21df55c06 | ||
| 9acbc60db2 | |||
| 5f2dda021a | |||
| 1244010c3d | |||
| 7226d54277 | |||
| eaafcdd444 | |||
| 9f9c02b7e7 | |||
|
|
7bffdda6b9 | ||
| 50d01ccd92 | |||
|
|
420573736d | ||
|
|
aca98cb7e6 | ||
|
|
f26fb83fec | ||
| 1ad9effe91 | |||
| 418d306d72 | |||
| 3606815a41 | |||
| 518e57ee44 | |||
| 872245c9c9 | |||
| 749f756d58 | |||
|
|
a22dfb6214 | ||
|
|
652e569e2b | ||
| d480986485 | |||
| 2e6efc69e8 | |||
| e2761049e5 | |||
| ee6a4288b0 | |||
| 7070f5c1b4 | |||
| cc4cc2f746 | |||
| 93e2a8af02 | |||
| 207811c41d | |||
|
|
8730a6396f | ||
| 05ff51bd48 | |||
| 1904eeb3ba | |||
|
|
70126171c6 | ||
|
|
ee084d6f33 | ||
| bacf4fd32f | |||
|
|
eaae58db31 | ||
|
|
13146595bf | ||
| b3083cdd18 | |||
| cf85870810 | |||
| 182e46799a | |||
| 27bd65d3da | |||
|
|
9fcc04cef2 | ||
| a1f07b8c20 | |||
|
|
65efa88d4a | ||
| 01a2d66585 | |||
| 098e9bf6ba | |||
| ddf56963bb | |||
|
|
eadcaf826b | ||
|
|
36248eaeef | ||
| 04496c3888 | |||
| 494aa6b52d | |||
|
|
4bb51506e3 | ||
|
|
112bec58df | ||
| 0b7a3cc50e | |||
| 9f517199fe | |||
| 2393a53466 | |||
| 80993c7d2d | |||
| 8c0a23d39a | |||
| a0949f0903 | |||
|
|
42052b7465 | ||
| a37a92e211 | |||
|
|
c3ddc62b95 | ||
|
|
0a3409f98a | ||
|
|
d26a687385 | ||
| 2f413e260e | |||
| 6fcb194995 | |||
| 7cea6b4f8d | |||
| 16d02c6936 | |||
| 289c93d824 | |||
| 8f99d68b6f | |||
| e0d7137727 | |||
|
|
7a9ed22ec9 | ||
|
|
af58ec755d | ||
| 4ad2020b57 | |||
| 1db24dae4b | |||
| 76055543c3 | |||
| a1d95d6a94 | |||
| 2143e3eb77 | |||
|
|
4a0901ea93 | ||
|
|
488bee514d | ||
|
|
bafea09e44 | ||
|
|
54923304dc | ||
|
|
8b357233c2 | ||
| 06b5f99930 | |||
| 0b5598346e | |||
|
|
d81e6b9f04 | ||
| 87e3dddac5 | |||
| 55f3ac577b | |||
| 0c053a028e | |||
| df36529619 | |||
| 7555510d94 | |||
|
|
2e986db686 | ||
| 660853d5be | |||
| 956bef4b90 | |||
|
|
43c22fca7c | ||
| 5db84c1e61 | |||
| 00c3e0cb77 | |||
| f4b6c46075 | |||
| 181bb5b445 | |||
|
|
90f58054fa | ||
| 137dbc72d8 | |||
|
|
a7cef3c6f8 | ||
| 339d460c0f | |||
| c8ba78f39b | |||
|
|
d31af73479 | ||
|
|
874800c19d | ||
|
|
404d45893f | ||
| ed6e95f380 | |||
| c4cfa0becd | |||
|
|
a069562bbe | ||
|
|
9158424a25 | ||
| 7488143037 | |||
| 99938f6ed6 | |||
|
|
1bde99f6c9 | ||
|
|
e3a9a037ba | ||
| b1d342f791 | |||
| 7639a70887 | |||
| f690cf0b62 | |||
| 4dcb12eb4f | |||
|
|
af5d8dbf19 | ||
| 9cd1638d55 | |||
| dd1570c10e | |||
| 3af7ca5d94 | |||
| 2d2cc21e15 | |||
| f872029c9d | |||
| 6198489dd4 | |||
| cce8e43c24 | |||
| cae0599307 | |||
|
|
2c6e88500a | ||
| efc20c644a | |||
| bdc43baaa8 | |||
| dc529b6640 | |||
|
|
488cc192b2 | ||
|
|
269f6c64a9 | ||
|
|
51186169ca | ||
|
|
325e57d1d5 | ||
| 862ec98fa3 | |||
| b827f7bfa6 | |||
|
|
786dfb54a3 | ||
|
|
a373738d70 | ||
| 6929276512 | |||
| 64c33f5709 | |||
| 7330e1ae2b | |||
| f359c9994d | |||
| d49b60a1e1 | |||
|
|
ee2cebdc41 | ||
| 1407ecc2f2 | |||
|
|
606fc64262 | ||
| a5516ebfb3 | |||
| dd7214a945 | |||
| a20571e050 | |||
| 8f7adb3079 | |||
| adcf005e62 | |||
|
|
8cff0195ad | ||
| 98940d7554 | |||
| 4a8c29365c | |||
| b641a65117 | |||
|
|
d747407d6b | ||
| f302155912 | |||
|
|
3d60814538 | ||
| 1293368d59 | |||
|
|
d1e1f5f4e8 | ||
|
|
b804c20ba0 | ||
| e030db04b9 | |||
| 0fcadde670 | |||
| e522d04ead | |||
|
|
ce0061e86e | ||
| 7ed4043a1f | |||
|
|
0b97d7bbaf | ||
| 5317f6d88f | |||
| 092b2ac519 | |||
| c9725875b3 | |||
| 6c33ac15f8 | |||
| af91783b9f | |||
| 5755aa5232 | |||
| ddc246e11c | |||
|
|
869ad9adf7 | ||
| 5356d91fef | |||
|
|
f024283e80 | ||
| 49167f332d | |||
| ea69f4bcb7 | |||
|
|
eaf973b927 | ||
| fdbf5aee04 | |||
| e4c490577d | |||
|
|
b5247df69b | ||
| d39ee17cc4 | |||
| 07da7acacd | |||
|
|
28add09f32 | ||
|
|
9d69610713 | ||
|
|
32969a58db | ||
| b188613035 | |||
| 308d5acc21 | |||
|
|
284b9784d6 | ||
| 26f02065df | |||
| eef852c283 | |||
| e0287899f8 | |||
| ae020b105a | |||
| 62c3cdcb30 | |||
| 01c657fdcb | |||
| 3a75e24601 | |||
| e28c393f88 | |||
| bfe8034b24 | |||
| c056dfe246 | |||
| a7cf09de1e | |||
| 7c4c22d69e | |||
| 3747f214b1 | |||
|
|
503fb0d7f1 | ||
|
|
6b0500b5ff | ||
| ae8c6cc23d | |||
| ad028c69d0 | |||
| 03b3398bce | |||
| 4a84283000 | |||
| c49c560e8d | |||
| 8d3ac7761f | |||
| a1d9b1f75b | |||
|
|
afed0c8833 | ||
| 415ed2fc9b | |||
| 8e45e17768 | |||
|
|
576a30d1be | ||
|
|
e380c8dcbc | ||
| 5e9f23286e | |||
| 1bbc78fb32 | |||
| b56368412c | |||
| 4ad75a11a8 | |||
| 3fa259c5b9 | |||
|
|
4cd4939c58 | ||
| b20141de02 | |||
| 9eff246f06 | |||
| 285a33ff9a | |||
|
|
7ebd935eba | ||
| f62a093092 | |||
| 28b4a36800 | |||
| ec59fce097 | |||
| e134ef8d54 | |||
| 29ddc68870 | |||
| 9ead9a6fb8 | |||
| 2a2672587c | |||
| 98122c25d8 | |||
| 84c89d7530 | |||
| 4268816539 | |||
| 721172d48a | |||
| 3e7942dbd4 | |||
| 17d18eff98 | |||
| 0d422177ac | |||
| 6336eab32a | |||
| f91a3f3fc1 | |||
| a489a6d00d | |||
| 8d8cff8d1b | |||
|
|
5f487f74bd | ||
| 857206e3da | |||
|
|
4ebe56913a | ||
|
|
efcc2591c2 | ||
|
|
455b330b7d | ||
|
|
ed2879e263 | ||
| 3b1c5ac1ec | |||
|
|
d243ffb380 | ||
| 6bdd81038b | |||
| 1eff58aca1 | |||
|
|
fa6eda5936 | ||
|
|
72f7e00dd5 | ||
| 707e083684 | |||
| 8b4f88c766 | |||
|
|
ae3ac93248 | ||
|
|
f43ccea32a | ||
|
|
73684b9962 | ||
|
|
80a1508dfc | ||
| 0b1393615c | |||
|
|
4481b102ef | ||
| cab59a5f4a | |||
| 9f6cd3fd6f | |||
|
|
4c5730d3bf | ||
|
|
1222aa9819 | ||
|
|
e58915edb6 | ||
|
|
4d4c251ebd | ||
|
|
6a416aaba1 | ||
| bbb25cde50 | |||
| 210749ebd3 | |||
| 637fedcbe6 | |||
|
|
70b05b85d7 | ||
| 9a1cefdb70 | |||
| 6ca8fb0c29 | |||
|
|
8e7de87c6b | ||
| cb55c09624 | |||
|
|
a41a58dc26 | ||
| f257c2b5a9 | |||
|
|
f5bd17f832 | ||
| 1b7296c13b | |||
| a965a83653 | |||
|
|
5cc521d93c | ||
| 6f2a893a4e | |||
| 1548b6f252 | |||
|
|
0c6b62ed1a | ||
|
|
1fcb3d312c | ||
| 35b24c261e | |||
| e5c5a2e5f5 | |||
| 9934d53390 | |||
| 030fdb6ad0 | |||
|
|
cf4948a3e2 | ||
| afd4cb6e41 | |||
| 596c9f9962 | |||
| 020bbf322d | |||
| 05b1a9bc74 | |||
| 7f001ba887 | |||
|
|
744de267dd | ||
|
|
af26dc24c7 | ||
|
|
e9fa533e5a | ||
| 3bd4301cda | |||
| 23be58c4e8 | |||
| 718d4a5d2f | |||
| 733678532a | |||
| 6fb29bbf60 | |||
| ecbfa57276 | |||
| fc59a6f182 | |||
| 83039d7b29 | |||
|
|
e405965298 | ||
|
|
e6766dc5eb | ||
| fe027e53db | |||
|
|
546d9b5728 | ||
| 7008ccc505 | |||
| 1fc8977f99 | |||
| 4acba02c6a | |||
|
|
491427feba | ||
|
|
249d251708 | ||
|
|
96eee88c82 | ||
|
|
7005895d90 | ||
|
|
3bdee09402 | ||
| 2843131151 | |||
| a8d4d64174 | |||
| 1853acd5eb | |||
|
|
03a4054ee5 | ||
| fe66792935 | |||
|
|
082c9d7d12 | ||
| e35eb5ac7f | |||
|
|
5e631652a9 | ||
| 4eb9adad78 | |||
| 4a9a8c3ec3 | |||
|
|
450047aae2 | ||
| eb65c0e101 | |||
| 6bd29ec63e | |||
| f0231be306 | |||
| b12547cd88 | |||
| ed6b531b8d | |||
| 47b9487e13 | |||
| ec40f8fa0d | |||
| 86a0a19fec | |||
| e0b69be2d4 | |||
| a2ad006a7e | |||
| 9b17c1225a | |||
|
|
32881d3f35 | ||
| e8367b8f1a | |||
| fc1bada607 | |||
| 1eca5b0309 | |||
| 08906e028a | |||
|
|
6e36e15ef3 | ||
| d71fe7d92e | |||
| 72ca2b7b04 | |||
| 5768ff5518 | |||
| 8a03b194b2 | |||
| 0d18a135ec | |||
| 91fdef55c7 | |||
|
|
4d437be248 | ||
| d42835231e | |||
| 3d117dbcb4 | |||
| 202aedbcf3 | |||
|
|
14a4bc4343 | ||
|
|
011322dd8e | ||
|
|
0d219e4b6d | ||
|
|
1972144384 | ||
|
|
08e7e6b461 | ||
| dbba33f085 | |||
| 4a637d0a69 | |||
|
|
a9d323354b | ||
|
|
4cd1c22d01 | ||
|
|
55ff7a1649 | ||
|
|
3deb3693b3 | ||
| 009efc2c86 | |||
| 40b37b49f9 | |||
| a3ad9a17c7 | |||
|
|
2c13c3dce1 | ||
|
|
859d884941 | ||
| 4a28abf5b7 | |||
| 527bb0f1d9 | |||
| 0429e7ca36 | |||
|
|
e8f13d7590 | ||
| 7eb3e567f6 | |||
| 17ec4753b6 | |||
| 2371ef1dee | |||
| c99d139940 | |||
| e0a2f7c798 | |||
| a12524dc9c | |||
|
|
c08cf6ea57 | ||
| 20746185e0 | |||
| 54cf0e213f | |||
|
|
6654fe0434 | ||
| 324917672c | |||
| d0a373123a | |||
| 86b7ad6d92 | |||
| c949667b94 | |||
| a61a41a068 | |||
| 06d241c66c | |||
| 62ed0ae78e | |||
| 1ee335abf2 | |||
|
|
05ee59618b | ||
|
|
fffa7cdabd | ||
| b8ec25c94e | |||
| 38029f7268 | |||
| d2fdccadf2 | |||
|
|
b1d06a4f1a | ||
|
|
ecf3a94b64 | ||
|
|
99b9af2980 | ||
|
|
267d07f3a5 | ||
| 977bfa910c | |||
| fe3c9c1563 | |||
|
|
8c11818b49 | ||
| ee0d8dd1a0 | |||
|
|
1d50f8e4f5 | ||
| e8f9884365 | |||
| 38f6f2f451 | |||
| a664ff7464 | |||
| a4ab6df974 | |||
| dc8f32062c | |||
| 0a090301df | |||
| d53d250e6f | |||
|
|
897a47bee7 | ||
| 0f457efce6 | |||
| 7842c1b838 | |||
| 02a5ceaacc | |||
| 6b1c223acd | |||
|
|
09a9e023d3 | ||
| 9b37374066 | |||
| 45257e8fe1 | |||
|
|
85971339d4 | ||
|
|
383e8c0859 | ||
| 749ac197de | |||
| d20210f291 | |||
|
|
da3398f1f9 | ||
| 81763110d7 | |||
| 6ac610e1aa | |||
|
|
362cc3814e | ||
| 37dfa05a25 | |||
|
|
2df205218c | ||
|
|
cceb697739 | ||
| 7d63869d44 | |||
| 3b1cecf8a3 | |||
| e52ec4a2b8 | |||
|
|
ed300eec30 | ||
| 8455c360fc | |||
| 059bfaf1d9 | |||
|
|
9f0b6897f1 | ||
| 2119d75e5b | |||
| af39c4bac0 | |||
| 93ac837148 | |||
| c4f3d10419 | |||
| 3f9cf21b8f | |||
| e9a8a4dc02 | |||
|
|
84f352a7fb | ||
| 834170e272 | |||
| 042f53e134 | |||
| 0b041bad7b | |||
| fe124dad0c | |||
|
|
7fe7178b27 | ||
|
|
9dcc23960e | ||
|
|
140e5740e6 | ||
|
|
752fae680c | ||
| e2f8e52583 | |||
| 4d573767f7 | |||
| 56475e729c | |||
| 8f0a1a09a6 | |||
|
|
c6b8b61b1e | ||
| 862295ff03 | |||
|
|
d13e42e33d | ||
| 134cdf2e2a | |||
| 44a05ea0d5 | |||
| 7f34c50b71 | |||
|
|
77682d310a | ||
| 2b0846f939 | |||
|
|
0b6c188e0a | ||
| f51f440b43 | |||
|
|
f74a01efc0 | ||
| 6dafa64e0b | |||
|
|
60453c756c | ||
|
|
350f17915a | ||
| ffcb847b02 | |||
| 8eae2c29ae | |||
|
|
5e55a5b94c | ||
| 1eee54fef1 | |||
| 24f691d4b8 | |||
| 1fc417ec25 | |||
| 71713e5b37 | |||
|
|
ef4c377990 | ||
| 88e27df986 | |||
| 628d9c7a1b | |||
|
|
7836c57479 | ||
|
|
939675fe58 | ||
| 5ed5b15737 | |||
| 783685942c | |||
| 30c09b0e26 | |||
| 96f21643b4 | |||
| 977067eda5 | |||
| 3e7279b4de | |||
| 34dd3ca883 | |||
|
|
d0d36ef207 | ||
| a66a32038c | |||
| 80d5bf3007 | |||
| cb39253785 | |||
| 3ec3350c97 | |||
| 7a01f62490 | |||
| 4a6bb9fd56 | |||
| 40532a0972 | |||
|
|
e059d9bbb2 | ||
| ab953b4785 | |||
|
|
6e38ef2962 | ||
|
|
6656aebff9 | ||
| 50b598d8a1 | |||
| cf08f8197b | |||
| 62f1912a7a | |||
| eae7f3d1a0 | |||
| b3e9836d7c | |||
| c3c91ba9a2 | |||
|
|
1075f7252a | ||
| 302435c068 | |||
| 41fb743bda | |||
|
|
823075c0ad | ||
|
|
c57486b69c | ||
| 8b3b0ce2ea | |||
| e3f9f21287 | |||
| b10d9ada46 | |||
| b48ceea571 | |||
|
|
0f2fbeb114 | ||
| 1623743b26 | |||
| 703f542abf | |||
| a2de293e10 | |||
|
|
a50abb5b2c | ||
|
|
2102acd9e5 | ||
|
|
b8ee197e52 | ||
|
|
ba81a46e2f | ||
|
|
6841f47ac3 | ||
| a2fef0990a | |||
| 9e411ecd71 | |||
| 8d14c06284 | |||
| 8b3f8d783e | |||
| b5ebc085b4 | |||
| 7e169e882d | |||
| 50f83939cc | |||
| f856188a68 | |||
| 7e9b794c7f | |||
|
|
e70a5e09f6 | ||
| 3e8db9ec7e | |||
| 34f70bb4cd | |||
|
|
12f78dc3b8 | ||
| 89a54276b3 | |||
| 73fb523ddc | |||
|
|
574d93d608 | ||
| 09687fb318 | |||
|
|
64bfc37bd7 | ||
|
|
a632e48d38 | ||
|
|
5570d29f32 | ||
|
|
c440b58981 | ||
|
|
6efd2898d7 | ||
|
|
a7c48675af | ||
|
|
7e9d2917b6 | ||
|
|
cb118e4a9f | ||
|
|
6e582829b2 | ||
| 30902825d6 | |||
| a4c56c7e28 | |||
| 26db1514d8 | |||
| 40cd824389 | |||
| fd687ab2d5 | |||
|
|
bab377a202 | ||
| f1554f8201 | |||
| 81933f0ad7 | |||
|
|
a16ae482a8 | ||
|
|
b688e671c1 | ||
| 476caa4be3 | |||
| d04a44044c | |||
| b394a8f9b5 | |||
| 07ae094bed | |||
|
|
4be0148324 | ||
| 025c8d74aa | |||
| f60aeaa35e | |||
| bf8e6de236 | |||
| 2c74fb78d9 | |||
| 78c4c455a8 | |||
| 135f8f5be3 | |||
| 32832654ef | |||
| 92ec8a3044 | |||
| cccde7a3f8 | |||
| 6efcb75c31 | |||
|
|
2e2e5c7ec0 | ||
|
|
c8ab6ffa15 | ||
|
|
8b180ce664 | ||
| fb0e35196c | |||
| 92233e1298 | |||
|
|
2891c3bf14 | ||
| 0f236f743d | |||
| 1d8cdf250d | |||
| 875fa33625 | |||
| 9c629937da | |||
| 38d2e0df57 | |||
|
|
c725be7bbc | ||
|
|
787d50c5b4 | ||
|
|
af7a8965a7 | ||
|
|
d8d29dd2ad | ||
| 22225eece6 | |||
| dad3f85864 | |||
| c83db0ec77 | |||
|
|
0b601738f7 | ||
| 2eba951ad1 | |||
| 0d6bf8adaa | |||
| bc87e143c8 | |||
|
|
92dfe89213 | ||
|
|
b0ba5b7d57 | ||
|
|
1959a7933b | ||
|
|
1ce5ac2c5f | ||
| 003f6622b9 | |||
|
|
7e00a5e71e | ||
|
|
172b37ece2 | ||
| b4e048bf74 | |||
| a0bff8a019 | |||
| 5db1021ecc | |||
|
|
7fabc4f1b6 | ||
| 6b7fd4d53e | |||
|
|
ab6e578336 | ||
|
|
e0861ff7eb | ||
| f9fd849ce0 | |||
|
|
60a132489a | ||
| a82d3984fa | |||
| ed97955d90 | |||
| 3be5f8b0cd | |||
| d2977fae85 | |||
| be0f81e059 | |||
|
|
099cc0d83d | ||
|
|
90e249e2d7 | ||
| 38a269ae1c | |||
| 77f5d89f28 | |||
|
|
1ecad0f89f | ||
|
|
c2d2687441 | ||
| f51237f04a | |||
|
|
5f27031620 | ||
|
|
e0a398a9fd | ||
|
|
05d4b29991 | ||
| dedb30d297 | |||
| c9743f28a3 | |||
| 512708284c | |||
|
|
d4d101843b | ||
|
|
11aeb95fd7 | ||
| 99e07bf861 | |||
| be735d9ca6 | |||
| 3dd9f3f551 | |||
|
|
f25f61b78c | ||
| 461a23a790 | |||
| 3c6b4d13a9 | |||
| 231ffcac84 | |||
|
|
845be4d795 | ||
| 6f40ff969d | |||
| 5559dd7eb2 | |||
|
|
5ec6a14ba1 | ||
| 1e2d146e74 | |||
|
|
217c5f3115 | ||
|
|
a09cbf4776 | ||
| 4330ee9d57 | |||
|
|
ad785f2b39 | ||
| 1501858a7d | |||
|
|
a49db975b1 | ||
| 79aadad668 | |||
| e4ba0b7f80 | |||
| ca03a8f23e | |||
|
|
4b5f3a9560 | ||
| 97fc07db0c | |||
| 28137615df | |||
| 00dfd38be5 | |||
| 99d32c03b2 | |||
|
|
80f23f4cc3 | ||
|
|
234756149c | ||
| ec1656fbbd | |||
|
|
baa596158d | ||
|
|
94c5f4b809 | ||
|
|
91743ecd3d | ||
| 0d12df93ab | |||
| 4070c7717b | |||
|
|
5bf95c28d2 | ||
| 09f74c3881 | |||
|
|
5f44473c49 | ||
|
|
842ef05dc7 | ||
| 814e45952c | |||
|
|
0eb6b68b5c | ||
|
|
47b6f9b45f | ||
| 780f9a3328 | |||
| fd038da6d7 | |||
| 9503f4a6c7 | |||
|
|
b8ff6d56ae | ||
| e352db3ced | |||
| 2cbc018764 | |||
|
|
9e02ad5119 | ||
|
|
2d122a93b7 | ||
|
|
8d0af1a06e | ||
| db1940c571 | |||
| b8e742cd08 | |||
| eb2aa91612 | |||
| fa4042bf42 | |||
| 9de86e545b | |||
|
|
b9977a3d90 | ||
| 99308f5ac5 | |||
| d86e68060c | |||
|
|
9212ed34cc | ||
|
|
62dc81d971 | ||
| 6d4e4f8566 | |||
|
|
88107b7ab5 | ||
| db81f4556a | |||
|
|
5b4912815a | ||
| 20916313dd | |||
|
|
c118a7c999 | ||
| 310fe91a19 | |||
| 1a8e7ecae9 | |||
|
|
447f8537f1 | ||
| 7e35cc8e3c | |||
|
|
3689a3a29d | ||
|
|
ca0dd85b8d | ||
|
|
0a25585c8e | ||
|
|
9b1e182fbd | ||
| f2a3f55e52 | |||
|
|
127490ca91 | ||
|
|
11d0afde56 | ||
|
|
0a6471163c | ||
|
|
8aefa10ef8 | ||
| c0fa59ce64 | |||
|
|
ce7433226d | ||
| d1e40abe2e | |||
| 8f37f3cc6d | |||
| f202fdd08d | |||
| 89c29fa442 | |||
| 1435848f2a | |||
|
|
5f9e27aa8a | ||
| 06bc518372 | |||
|
|
ee7374d816 | ||
| 5060d647fb | |||
| 3a87583340 | |||
|
|
a6004941ad | ||
|
|
e2095f6e46 | ||
|
|
8cf76a13e0 | ||
| bc553a1b1d | |||
|
|
80655a8662 | ||
|
|
a1633e3456 | ||
| 340217e922 | |||
| f10316bf57 | |||
|
|
b279bb1083 | ||
| d7d980860c | |||
|
|
575d870dcc | ||
| 2f97839619 | |||
| 92e435f6b6 | |||
| 5c349902dd | |||
|
|
72dd63355e | ||
| dd97d35851 | |||
|
|
39b4a52ade | ||
|
|
dea52ee452 | ||
|
|
b7129bcbfa | ||
| 1f0a95ad0f | |||
|
|
81f701e915 | ||
|
|
b8d9e3a3c3 | ||
|
|
c7b81a5185 | ||
|
|
a066d3f4ff | ||
|
|
45d9b914a9 | ||
|
|
6aaadb6e9a | ||
|
|
3953b0c285 | ||
| 3a259290f8 | |||
| 05c490672d | |||
|
|
b9c6b4afec | ||
|
|
e2a151a5af | ||
|
|
93e25f58f5 | ||
| c9895781d5 | |||
| c45cc7a990 | |||
|
|
62ff407cab | ||
|
|
8d98c6b5cc | ||
|
|
0d473bdd9f | ||
|
|
039134b7d2 | ||
| 51c6ed3456 | |||
|
|
79a4c560df | ||
|
|
cadbf53086 | ||
|
|
9e527d6a5d | ||
|
|
2490c6bdd1 | ||
|
|
44c6e5e4cd | ||
| 25252b013b | |||
| 683f1d5835 | |||
| ec730e850a | |||
| 59256c9cf7 | |||
|
|
20bd0d884c | ||
|
|
9509ac721e | ||
|
|
874ee86a10 | ||
| f0941ffd26 | |||
| 2fdc4001f4 | |||
| 04f0953cfa | |||
| 7033f5e707 | |||
| 7f423a9ae2 | |||
| a9302d3e54 | |||
|
|
f52e10b96f | ||
| ff7bfc040d | |||
| 24e07db6e1 | |||
| fa12ce88d7 | |||
| e749e1a7d5 | |||
| c0d0fed83a | |||
|
|
aaa453c903 | ||
| 0b0967f84d | |||
| 1e98de9931 | |||
|
|
ab2991a999 | ||
| d2bb4e4375 | |||
|
|
6bc3019b02 | ||
| 80c5609bb7 | |||
| e29ecd2845 | |||
|
|
82ccf66d80 | ||
|
|
f8826d0239 | ||
|
|
362dff002f | ||
|
|
a5826b2dc3 | ||
|
|
83aed0bedb | ||
| bdaa51dbb6 | |||
| 02206dc289 | |||
| d1d31da6be | |||
|
|
d77721a0bc | ||
|
|
567e403151 | ||
|
|
1cdf065839 | ||
|
|
a555019561 | ||
|
|
86735ab81f | ||
|
|
1935ac14f0 | ||
|
|
f531fd4d0e | ||
| c634d29e79 | |||
|
|
0de802bf3c | ||
|
|
8b4d25bbeb | ||
|
|
8c75b80535 | ||
|
|
6fef3ee243 | ||
| 8ef917ebb6 | |||
| 333e4fc1e6 | |||
|
|
c95fd2d49c | ||
|
|
fc0c734261 | ||
|
|
0cafd76035 | ||
|
|
bebf19215e | ||
|
|
5e581dd65e | ||
|
|
3225cf5d5f | ||
|
|
1c16a673fd | ||
|
|
bf9d573727 | ||
| 882c5ff95c | |||
| c6770c1d51 | |||
|
|
01ea24c66c | ||
| 56d790082a | |||
| e7a8cd781b | |||
|
|
264d000111 | ||
|
|
ada42b1981 | ||
| e455f1c3a0 | |||
| 3e776b63c4 | |||
| 7ef6c95c63 | |||
|
|
0af40fa7e5 | ||
|
|
169bf74f31 | ||
|
|
ad1599ccce | ||
|
|
5bd0f455bb | ||
| 18069a726d | |||
| c1c7c71f4a | |||
| 211874b3ae | |||
| 7d72a65f89 | |||
| dd39064ca5 | |||
| 89ed3f5121 |
1
FaceUnity/.gitignore
vendored
Normal file
1
FaceUnity/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
74
FaceUnity/build.gradle
Normal file
74
FaceUnity/build.gradle
Normal file
@@ -0,0 +1,74 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'img-optimizer'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-parcelize'
|
||||
apply from: "../package_config.gradle"
|
||||
|
||||
android {
|
||||
namespace "com.yunbao.faceunity"
|
||||
compileSdk rootProject.ext.android.compileSdkVersion
|
||||
packagingOptions {
|
||||
pickFirst "lib/armeabi/libyuvutils.so"
|
||||
pickFirst "lib/arm64-v8a/libyuvutils.so"
|
||||
pickFirst "lib/armeabi-v7a/libyuvutils.so"
|
||||
pickFirst "lib/armeabi/libyuvtools.so"
|
||||
pickFirst "lib/arm64-v8a/libyuvtools.so"
|
||||
pickFirst "lib/armeabi-v7a/libyuvtools.so"
|
||||
exclude "lib/arm64-v8a/libmmcv_api_handgesture.so"
|
||||
exclude "lib/arm64-v8a/libmmcv_api_express.so"
|
||||
exclude "lib/arm64-v8a/libMediaEncoder.so"
|
||||
exclude "lib/arm64-v8a/libarcore_sdk_c.so"
|
||||
exclude "lib/arm64-v8a/libmediadecoder.so"
|
||||
exclude "lib/arm64-v8a/libMediaMuxer.so"
|
||||
exclude "lib/arm64-v8a/libarcore_sdk_jni.so"
|
||||
exclude "lib/arm64-v8a/libMediaUtils.so"
|
||||
exclude "lib/arm64-v8a/libcosmosffmpeg.so"
|
||||
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.android.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.android.targetSdkVersion
|
||||
versionCode rootProject.ext.android.versionCode
|
||||
versionName rootProject.ext.android.versionName
|
||||
manifestPlaceholders = rootProject.ext.manifestPlaceholders
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "arm64-v8a"
|
||||
// abiFilters "armeabi-v7a", "arm64-v8a","x86","x86_64"
|
||||
}
|
||||
}
|
||||
aaptOptions {
|
||||
cruncherEnabled = false
|
||||
useNewCruncher = false
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_18
|
||||
targetCompatibility JavaVersion.VERSION_18
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
flatDir {
|
||||
dirs 'libs', '../libs'
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||
api rootProject.ext.dependencies["appcompat-androidx"]
|
||||
api rootProject.ext.dependencies["recyclerview-androidx"]
|
||||
api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
//common
|
||||
api project(path: ':common')
|
||||
|
||||
api 'com.faceunity:core:8.7.0'
|
||||
api 'com.faceunity:model:8.7.0'
|
||||
//implementation 'com.faceunity:nama:8.3.1' //底层库-标准版
|
||||
|
||||
|
||||
}
|
||||
0
FaceUnity/consumer-rules.pro
Normal file
0
FaceUnity/consumer-rules.pro
Normal file
21
FaceUnity/proguard-rules.pro
vendored
Normal file
21
FaceUnity/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.yunbao.faceunity;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.Instrimport com.yunbao.common.utils.MobclickAgent;ntationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("com.yunbao.faceunity.test", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
16
FaceUnity/src/main/AndroidManifest.xml
Normal file
16
FaceUnity/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:icon="@mipmap/ico_home_animoji"
|
||||
android:allowBackup="true">
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
271
FaceUnity/src/main/java/com/yunbao/faceunity/FaceManager.java
Normal file
271
FaceUnity/src/main/java/com/yunbao/faceunity/FaceManager.java
Normal file
@@ -0,0 +1,271 @@
|
||||
package com.yunbao.faceunity;
|
||||
|
||||
import static android.content.Context.SENSOR_SERVICE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
import com.faceunity.core.entity.FURenderOutputData;
|
||||
import com.faceunity.core.enumeration.CameraFacingEnum;
|
||||
import com.faceunity.core.enumeration.FUAIProcessorEnum;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.enumeration.FUInputTextureEnum;
|
||||
import com.faceunity.core.enumeration.FUTransformMatrixEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.utils.CameraUtils;
|
||||
import com.yunbao.faceunity.data.FaceBeautyDataFactory;
|
||||
import com.yunbao.faceunity.data.FaceUnityDataFactory;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyBean;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyFilterBean;
|
||||
import com.yunbao.faceunity.listener.FURendererListener;
|
||||
import com.yunbao.faceunity.ui.FaceUnityView;
|
||||
import com.yunbao.faceunity.utils.CSVUtils;
|
||||
import com.yunbao.faceunity.utils.FURenderer;
|
||||
import com.yunbao.faceunity.utils.FaceSPUtils;
|
||||
import com.yunbao.faceunity.utils.FaceUnityData;
|
||||
import com.yunbao.faceunity.utils.net.OkHttpUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* 美颜模块管理类
|
||||
*/
|
||||
public class FaceManager implements SensorEventListener {
|
||||
private static boolean isInit = false;
|
||||
private static final String TAG = FaceManager.class.getSimpleName();
|
||||
private FaceUnityDataFactory mFaceUnityDataFactory;
|
||||
private FaceManager.FaceStatusChanged faceStatusChanged;
|
||||
private boolean pauseFace = false;
|
||||
|
||||
/**
|
||||
* 初始化美颜模块,在AppContext中调用
|
||||
*/
|
||||
public static void initFaceUnity(Context context) {
|
||||
if (isInit) {
|
||||
return;
|
||||
}
|
||||
FaceUnityData.mApplication = context;
|
||||
OkHttpUtils.getInstance().init(context, false);
|
||||
FURenderer.getInstance().setup(context);
|
||||
isInit = true;
|
||||
}
|
||||
|
||||
private FURenderer mFURenderer;
|
||||
|
||||
/**
|
||||
* 配置美颜SDK
|
||||
*/
|
||||
public void initFURender(Context context) {
|
||||
initFaceUnity(context);
|
||||
mFURenderer = FURenderer.getInstance();
|
||||
mFURenderer.setInputTextureType(FUInputTextureEnum.FU_ADM_FLAG_COMMON_TEXTURE);
|
||||
mFURenderer.setCameraFacing(CameraFacingEnum.CAMERA_FRONT);
|
||||
mFURenderer.setInputBufferMatrix(FUTransformMatrixEnum.CCROT90_FLIPHORIZONTAL);
|
||||
mFURenderer.setInputTextureMatrix(FUTransformMatrixEnum.CCROT90_FLIPHORIZONTAL);
|
||||
mFURenderer.setOutputMatrix(FUTransformMatrixEnum.CCROT270);
|
||||
mFURenderer.setInputOrientation(CameraUtils.INSTANCE.getCameraOrientation(Camera.CameraInfo.CAMERA_FACING_FRONT));
|
||||
mFURenderer.setMarkFPSEnable(true);
|
||||
mFaceUnityDataFactory = FaceUnityDataFactory.getInstance();
|
||||
|
||||
SensorManager mSensorManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);
|
||||
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册长按对比键事件
|
||||
*
|
||||
* @param faceUnityView
|
||||
*/
|
||||
public void setFaceUnityView(FaceUnityView faceUnityView) {
|
||||
faceUnityView.setIFaceUnityInter(new FaceUnityView.IFaceUnityInter() {
|
||||
@Override
|
||||
public void onPause() {
|
||||
if(onMirrorChanged!=null){
|
||||
onMirrorChanged.onChange(false);
|
||||
}
|
||||
pauseFace = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
if(onMirrorChanged!=null){
|
||||
onMirrorChanged.onChange(true);
|
||||
}
|
||||
pauseFace = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loadConfig() {
|
||||
initFaceBeauty();
|
||||
}
|
||||
|
||||
public void initFaceBeauty() {
|
||||
FaceBeautyDataFactory faceBeautyDataFactory;
|
||||
faceBeautyDataFactory = new FaceBeautyDataFactory();
|
||||
Map<String, ?> configMap = FaceSPUtils.getInstance().getAll();
|
||||
for (String key : configMap.keySet()) {
|
||||
if ("FilterViewHolder_".equals(key)) {
|
||||
for (FaceBeautyFilterBean filter : faceBeautyDataFactory.getBeautyFilters()) {
|
||||
if (filter.getKey().equals(configMap.get(key)) && !"origin".equals(configMap.get(key))) {
|
||||
try {
|
||||
faceBeautyDataFactory.onFilterSelected(filter.getKey(), Double.parseDouble((String) Objects.requireNonNull(configMap.get("FilterViewHolder_" + configMap.get(key) + "_val"))) / 100, filter.getDesRes());
|
||||
Log.i(TAG, "test: 设置滤镜 =" + filter.getKey() + " val = " + configMap.get("FilterViewHolder_" + configMap.get(key) + "_val"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (key.startsWith("BeautySkinViewHolder_")) {
|
||||
String name = key.replace("BeautySkinViewHolder_", "");
|
||||
for (FaceBeautyBean bean : faceBeautyDataFactory.getShapeBeauty()) {
|
||||
if (bean.getKey().equals(name)) {
|
||||
try {
|
||||
faceBeautyDataFactory.updateParamIntensity(bean.getKey(), Double.parseDouble((String) Objects.requireNonNull(configMap.get(key))));
|
||||
Log.i(TAG, "test: 设置美颜 = " + bean.getKey() + " val = " + configMap.get(key));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (key.startsWith("BeautyShapeViewHolder")) {
|
||||
String name = key.replace("BeautyShapeViewHolder_", "");
|
||||
for (FaceBeautyBean bean : faceBeautyDataFactory.getShapeBeauty()) {
|
||||
if (bean.getKey().equals(name)) {
|
||||
try {
|
||||
faceBeautyDataFactory.updateParamIntensity(bean.getKey(), Double.parseDouble((String) Objects.requireNonNull(configMap.get(key))));
|
||||
Log.i(TAG, "test: 设置美肤 = " + bean.getKey() + " val = " + configMap.get(key));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听人脸识别个数
|
||||
*/
|
||||
public void setFaceStatusChanged(FaceStatusChanged faceStatusChanged) {
|
||||
this.faceStatusChanged = faceStatusChanged;
|
||||
}
|
||||
|
||||
private boolean mIsFirstFrame = true;
|
||||
private CSVUtils mCSVUtils;
|
||||
private int mSkippedFrames = CAMERA_SWITCH_SKIP_FRAME;
|
||||
// 相机切换跳过 5 帧,如果还有问题,可以增加帧数
|
||||
private static final int CAMERA_SWITCH_SKIP_FRAME = 0;
|
||||
private volatile boolean mSkip;
|
||||
|
||||
|
||||
/**
|
||||
* 记录渲染工具,调试用,在processVideoFrame里使用
|
||||
*/
|
||||
private void initCsvUtil(Context context) {
|
||||
mCSVUtils = new CSVUtils(context);
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault());
|
||||
String dateStrDir = format.format(new Date(System.currentTimeMillis()));
|
||||
dateStrDir = dateStrDir.replaceAll("-", "").replaceAll("_", "");
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS", Locale.getDefault());
|
||||
String dateStrFile = df.format(new Date());
|
||||
String filePath = Environment.getExternalStoragePublicDirectory("") + dateStrDir + File.separator + "excel-" + dateStrFile + ".csv";
|
||||
Log.d("CSV", "initLog: CSV file path:" + filePath);
|
||||
StringBuilder headerInfo = new StringBuilder();
|
||||
headerInfo.append("version:").append(FURenderer.getInstance().getVersion()).append(CSVUtils.COMMA)
|
||||
.append("机型:").append(android.os.Build.MANUFACTURER).append(android.os.Build.MODEL)
|
||||
.append("处理方式:Texture").append(CSVUtils.COMMA);
|
||||
mCSVUtils.initHeader(filePath, headerInfo);
|
||||
}
|
||||
|
||||
|
||||
private FURendererListener mFURendererListener = new FURendererListener() {
|
||||
|
||||
@Override
|
||||
public void onPrepare() {
|
||||
mFaceUnityDataFactory.bindCurrentRenderer();
|
||||
//Log.e(TAG, "mFURendererListener: onPrepare: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackStatusChanged(FUAIProcessorEnum type, int status) {
|
||||
Log.e(TAG, "onTrackStatusChanged: 人脸数: " + status);
|
||||
if (faceStatusChanged != null) {
|
||||
faceStatusChanged.onFaceChanged(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFpsChanged(double fps, double callTime) {
|
||||
final String FPS = String.format(Locale.getDefault(), "%.2f", fps);
|
||||
// Log.d(TAG, "onFpsChanged FPS: " + FPS + ", callTime: " + String.format("%.2f", callTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelease() {
|
||||
// RongCallClient.getInstance().unregisterVideoFrameObserver();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent sensorEvent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int i) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 释放资源
|
||||
*/
|
||||
public void release() {
|
||||
mFURenderer.release();
|
||||
try {
|
||||
for (FUAITypeEnum value : FUAITypeEnum.values()) {
|
||||
FUAIKit.getInstance().releaseAIProcessor(value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
isInit = false;
|
||||
|
||||
}
|
||||
|
||||
OnMirrorChanged onMirrorChanged;
|
||||
|
||||
public void setOnMirrorChanged(OnMirrorChanged onMirrorChanged) {
|
||||
this.onMirrorChanged = onMirrorChanged;
|
||||
}
|
||||
|
||||
public interface FaceStatusChanged {
|
||||
void onFaceChanged(int num);
|
||||
}
|
||||
|
||||
|
||||
public interface OnMirrorChanged{
|
||||
void onChange(boolean falg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
package com.yunbao.faceunity.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.yunbao.common.utils.DpUtil;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.adapters.vh.AnimViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.AnimojiViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.BaseViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.BeautyBodyViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.BeautyShapeViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.BeautySkinViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.BigHeadViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.FilterViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.FineStickerViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.MakeupCustomItemViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.MakeupViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.StickerViewHolder;
|
||||
import com.yunbao.faceunity.adapters.vh.StyleViewHolder;
|
||||
import com.yunbao.faceunity.data.AnimojiDataFactory;
|
||||
import com.yunbao.faceunity.data.BodyBeautyDataFactory;
|
||||
import com.yunbao.faceunity.data.FaceBeautyDataFactory;
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
import com.yunbao.faceunity.data.FineStickerDataFactory;
|
||||
import com.yunbao.faceunity.data.MakeupDataFactory;
|
||||
import com.yunbao.faceunity.data.PropDataFactory;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.PropBean;
|
||||
import com.yunbao.faceunity.seekbar.DiscreteSeekBar;
|
||||
import com.yunbao.faceunity.utils.FaceSPUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 美颜配置适配器
|
||||
*/
|
||||
public class ContainerRecyclerAdapter extends RecyclerView.Adapter<BaseViewHolder> {
|
||||
|
||||
private Context mContext;
|
||||
private List<? extends BaseBean> list;
|
||||
public int selectPosition = -1;
|
||||
private FaceBeautyDataFactory faceBeautyDataFactory;//美颜工厂
|
||||
private MakeupDataFactory makeupDataFactory;//美妆工厂
|
||||
private BodyBeautyDataFactory bodyBeautyDataFactory;//美体工厂
|
||||
private PropDataFactory propDataFactory;//道具业务工厂:道具贴图、AR面具、搞笑大头、表情识别、哈哈镜、手势识别
|
||||
private AnimojiDataFactory animojiDataFactory;//Animoji工厂
|
||||
private FineStickerDataFactory fineStickerDataFactory;//精品贴图
|
||||
private DiscreteSeekBar seekBar;
|
||||
private float seekY = 0;
|
||||
|
||||
public ContainerRecyclerAdapter(Context mContext) {
|
||||
this.mContext = mContext;
|
||||
initDataFactory();
|
||||
}
|
||||
|
||||
public void setSeekBar(DiscreteSeekBar seekBar) {
|
||||
this.seekBar = seekBar;
|
||||
}
|
||||
|
||||
public DiscreteSeekBar getSeekBar() {
|
||||
return seekBar;
|
||||
}
|
||||
|
||||
public void showSeekBar() {
|
||||
if (seekBar.getVisibility() == View.VISIBLE) {
|
||||
return;
|
||||
}
|
||||
seekBar.setVisibility(View.VISIBLE);
|
||||
if (seekY == 0) {
|
||||
seekY = seekBar.getY() - DpUtil.dp2px(20);
|
||||
}
|
||||
seekBar.setY(seekY);
|
||||
}
|
||||
|
||||
public void hideSeekBar() {
|
||||
if (seekBar.getVisibility() == View.INVISIBLE) {
|
||||
return;
|
||||
}
|
||||
seekBar.setOnProgressChangeListener(null);
|
||||
seekBar.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
|
||||
private void initDataFactory() {
|
||||
faceBeautyDataFactory = new FaceBeautyDataFactory(new FaceBeautyDataFactory.FaceBeautyListener() {
|
||||
@Override
|
||||
public void onFilterSelected(int res) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFaceBeautyEnable(boolean enable) {
|
||||
|
||||
}
|
||||
});
|
||||
propDataFactory = new PropDataFactory(new PropDataFactory.PropListener() {
|
||||
@Override
|
||||
public void onItemSelected(PropBean bean) {
|
||||
|
||||
}
|
||||
}, 0, 0);
|
||||
animojiDataFactory = new AnimojiDataFactory(0, 0);
|
||||
makeupDataFactory = new MakeupDataFactory(0);
|
||||
bodyBeautyDataFactory = new BodyBeautyDataFactory();
|
||||
bodyBeautyDataFactory.bindCurrentRenderer();
|
||||
}
|
||||
|
||||
public void setList(ArrayList<? extends BaseBean> list) {
|
||||
this.list = list;
|
||||
this.selectPosition = -1;
|
||||
hideSeekBar();
|
||||
}
|
||||
|
||||
public int getSelectPosition() {
|
||||
return selectPosition;
|
||||
}
|
||||
|
||||
public void setSelectPosition(int selectPosition) {
|
||||
this.selectPosition = selectPosition;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public FaceBeautyDataFactory getFaceBeautyDataFactory() {
|
||||
return faceBeautyDataFactory;
|
||||
}
|
||||
|
||||
public MakeupDataFactory getMakeupDataFactory() {
|
||||
return makeupDataFactory;
|
||||
}
|
||||
|
||||
public BodyBeautyDataFactory getBodyBeautyDataFactory() {
|
||||
return bodyBeautyDataFactory;
|
||||
}
|
||||
|
||||
public PropDataFactory getPropDataFactory() {
|
||||
return propDataFactory;
|
||||
}
|
||||
|
||||
public AnimojiDataFactory getAnimojiDataFactory() {
|
||||
return animojiDataFactory;
|
||||
}
|
||||
|
||||
BaseViewHolder vh = null;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater from = LayoutInflater.from(mContext);
|
||||
switch (viewType) {
|
||||
case FaceParam.FACE_BEAUTY_SKIN:
|
||||
vh = new BeautySkinViewHolder(from.inflate(R.layout.list_item_face_config, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_BEAUTY_SHAPE:
|
||||
vh = new BeautyShapeViewHolder(from.inflate(R.layout.list_item_face_config, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_BEAUTY_BODY:
|
||||
vh = new BeautyBodyViewHolder(from.inflate(R.layout.list_item_face_config, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_BEAUTY_FILTER:
|
||||
vh = new FilterViewHolder(from.inflate(R.layout.list_item_face_config_filter, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP:
|
||||
vh = new MakeupViewHolder(from.inflate(R.layout.list_item_face_config_filter, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_BEAUTY_STYLE:
|
||||
vh = new StyleViewHolder(from.inflate(R.layout.list_item_face_config_style, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_ANIMOJI:
|
||||
vh = new AnimojiViewHolder(from.inflate(R.layout.list_item_face_config_big_head, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_ANIM:
|
||||
vh = new AnimViewHolder(from.inflate(R.layout.list_item_face_config_big_head, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_STICKER:
|
||||
vh = new StickerViewHolder(from.inflate(R.layout.list_item_face_config_big_head, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_BIG_HEAD:
|
||||
vh = new BigHeadViewHolder(from.inflate(R.layout.list_item_face_config_big_head, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_FINE_STICKER:
|
||||
case FaceParam.FACE_FINE_STICKER_MIDDLE:
|
||||
case FaceParam.FACE_FINE_STICKER_HIGH:
|
||||
case FaceParam.FACE_FINE_STICKER_GAME:
|
||||
vh = new FineStickerViewHolder(from.inflate(R.layout.list_item_face_config_fine_sticker, parent, false));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_FOUNDATION:
|
||||
case FaceParam.FACE_MAKEUP_TYPE_LIP_STICK:
|
||||
case FaceParam.FACE_MAKEUP_TYPE_BLUSHER:
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_BROW:
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW:
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_LINER:
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_LASH:
|
||||
case FaceParam.FACE_MAKEUP_TYPE_HIGH_LIGHT:
|
||||
case FaceParam.FACE_MAKEUP_TYPE_SHADOW:
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL:
|
||||
vh = new MakeupCustomItemViewHolder(from.inflate(R.layout.list_item_face_config_filter, parent, false));
|
||||
break;
|
||||
default:
|
||||
vh = new BeautySkinViewHolder(LayoutInflater.from(mContext).inflate(R.layout.list_item_face_config, parent, false));
|
||||
}
|
||||
vh.adapter = this;
|
||||
return vh;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return list.get(position).getBeanType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
|
||||
holder.setData(list.get(position));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存配置
|
||||
*/
|
||||
public void save(String key, String data) {
|
||||
FaceSPUtils.getInstance().saveString(key, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取配置
|
||||
*/
|
||||
public String getString(String key) {
|
||||
return FaceSPUtils.getInstance().getString(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配置
|
||||
*/
|
||||
public void del(String key) {
|
||||
FaceSPUtils.getInstance().del(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复默认设置
|
||||
*/
|
||||
public void reset() {
|
||||
if (vh != null) {
|
||||
vh.reset(list);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.yunbao.faceunity.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.yunbao.common.adapter.OnItemClickListener;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.MenuGroupBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 主菜单适配器
|
||||
*/
|
||||
public class MenuGroupRecyclerAdapter extends RecyclerView.Adapter<MenuGroupRecyclerAdapter.Vh> {
|
||||
private Context context;
|
||||
private List<MenuGroupBean> list;
|
||||
private OnItemClickListener onItemClickListener;
|
||||
|
||||
public MenuGroupRecyclerAdapter(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
|
||||
this.onItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
public void setList(List<MenuGroupBean> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Vh onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new Vh(LayoutInflater.from(context).inflate(R.layout.list_item_menu_group, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull Vh holder, int position) {
|
||||
holder.setData(list.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
|
||||
protected class Vh extends RecyclerView.ViewHolder {
|
||||
ImageView icon;
|
||||
TextView title;
|
||||
|
||||
public Vh(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.item_icon);
|
||||
title = itemView.findViewById(R.id.item_text);
|
||||
itemView.setOnClickListener(v -> {
|
||||
if (onItemClickListener != null) {
|
||||
onItemClickListener.onItemClick(getAdapterPosition());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setData(MenuGroupBean menuGroupBean) {
|
||||
icon.setImageResource(menuGroupBean.getIconId());
|
||||
title.setText(menuGroupBean.getTitleId());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.AnimationFilterBean;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 动画滤镜 *暂无权限
|
||||
*/
|
||||
public class AnimViewHolder extends BaseViewHolder {
|
||||
ImageView icon;
|
||||
|
||||
public AnimViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.iv_control);
|
||||
TextView title = itemView.findViewById(R.id.tv_control);
|
||||
title.setVisibility(View.GONE);
|
||||
icon.setBackgroundResource(R.drawable.bg_control_square_selector);
|
||||
itemView.setOnClickListener(v -> {
|
||||
adapter.getAnimojiDataFactory().onFilterSelected((AnimationFilterBean) itemView.getTag());
|
||||
setSelectPosition(getAdapterPosition());
|
||||
saveData();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageResource(data.getImageRes());
|
||||
icon.setSelected(getAdapterPosition() == getSelectPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
adapter.setSelectPosition(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.common.utils.ToastUtil;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.AnimojiBean;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Animoji
|
||||
*/
|
||||
public class AnimojiViewHolder extends BaseViewHolder {
|
||||
ImageView icon;
|
||||
TextView title;
|
||||
|
||||
public AnimojiViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.iv_control);
|
||||
title = itemView.findViewById(R.id.tv_control);
|
||||
title.setVisibility(View.GONE);
|
||||
itemView.setOnClickListener(v -> {
|
||||
adapter.getAnimojiDataFactory().onAnimojiSelected((AnimojiBean) itemView.getTag());
|
||||
setSelectPosition(getLayoutPosition());
|
||||
saveData();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageResource(data.getImageRes());
|
||||
int adapterPosition = getAdapterPosition();
|
||||
int selectPosition = getSelectPosition();
|
||||
if (loadData()) {
|
||||
return;
|
||||
}
|
||||
icon.setSelected(adapterPosition == selectPosition);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
String data = adapter.getString(getName(this));
|
||||
if (data == null) {
|
||||
return false;
|
||||
}
|
||||
if (!data.equals(String.valueOf(getLayoutPosition()))) {
|
||||
return false;
|
||||
}
|
||||
icon.setSelected(true);
|
||||
adapter.getAnimojiDataFactory().onAnimojiSelected((AnimojiBean) itemView.getTag());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
adapter.save(getName(this), String.valueOf(getLayoutPosition()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
adapter.save(getName(this),"0");
|
||||
adapter.getAnimojiDataFactory().onAnimojiSelected((AnimojiBean) list.get(0));
|
||||
adapter.setSelectPosition(0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.yunbao.faceunity.adapters.ContainerRecyclerAdapter;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseViewHolder extends RecyclerView.ViewHolder {
|
||||
public ContainerRecyclerAdapter adapter;
|
||||
|
||||
public int getSelectPosition() {
|
||||
return adapter.selectPosition;
|
||||
}
|
||||
|
||||
public void setSelectPosition(int selectPosition) {
|
||||
adapter.selectPosition = selectPosition;
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public BaseViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
public String getName(Object obj){
|
||||
return obj.getClass().getSimpleName()+"_";
|
||||
}
|
||||
|
||||
public abstract void setData(BaseBean data);
|
||||
|
||||
/**
|
||||
* 读取配置
|
||||
* @return 是否有保存的配置
|
||||
*/
|
||||
public abstract boolean loadData();
|
||||
|
||||
/**
|
||||
* 保存配置
|
||||
*/
|
||||
public abstract void saveData();
|
||||
|
||||
/**
|
||||
* 恢复默认配置
|
||||
*/
|
||||
public abstract void reset(List<? extends BaseBean> list);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.BodyBeautyBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.seekbar.DiscreteSeekBar;
|
||||
import com.yunbao.faceunity.utils.SeekBarUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 美体
|
||||
*/
|
||||
public class BeautyBodyViewHolder extends BaseViewHolder {
|
||||
private ImageView icon;
|
||||
private TextView title;
|
||||
private TextView value;
|
||||
private DiscreteSeekBar seekBar;
|
||||
|
||||
public BeautyBodyViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.item_icon);
|
||||
title = itemView.findViewById(R.id.item_title);
|
||||
value = itemView.findViewById(R.id.item_value);
|
||||
seekBar = itemView.findViewById(R.id.item_seekBar);
|
||||
seekBar.setOnProgressChangeListener(new DiscreteSeekBar.OnSimpleProgressChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) {
|
||||
super.onProgressChanged(seekBar, value, fromUser);
|
||||
BodyBeautyBean bean = (BodyBeautyBean) itemView.getTag();
|
||||
double toValue = SeekBarUtils.Companion.seekToValue(bean.getModelAttributeData().getMaxRange(), value, seekBar.getMin());
|
||||
BeautyBodyViewHolder.this.value.setText(String.format("%.1f", toValue));
|
||||
adapter.getBodyBeautyDataFactory().updateParamIntensity(bean.getKey(), toValue);
|
||||
saveData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageResource(data.getImageRes());
|
||||
title.setText(data.getDesRes());
|
||||
if (loadData()) {
|
||||
return;
|
||||
}
|
||||
ModelAttributeData attributeData = data.getModelAttributeData();
|
||||
value.setText(attributeData.getDefault() + "");
|
||||
SeekBarUtils.Companion.seekToSeekBar(seekBar,
|
||||
attributeData.getDefault(),
|
||||
attributeData.getStand(),
|
||||
attributeData.getMaxRange());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
BodyBeautyBean bean = (BodyBeautyBean) itemView.getTag();
|
||||
String val = adapter.getString(getName(this) + bean.getKey());
|
||||
if (val == null) {
|
||||
return false;
|
||||
}
|
||||
ModelAttributeData attributeData = bean.getModelAttributeData();
|
||||
value.setText(val);
|
||||
SeekBarUtils.Companion.seekToSeekBar(seekBar,
|
||||
Double.parseDouble(val),
|
||||
attributeData.getStand(),
|
||||
attributeData.getMaxRange());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
BodyBeautyBean bean = (BodyBeautyBean) itemView.getTag();
|
||||
String key = getName(this) + bean.getKey();
|
||||
adapter.save(key, (String) value.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
String name = getName(this);
|
||||
for (BaseBean bean : list) {
|
||||
adapter.del(name + bean.getKey());
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.seekbar.DiscreteSeekBar;
|
||||
import com.yunbao.faceunity.utils.SeekBarUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 美型
|
||||
*/
|
||||
public class BeautyShapeViewHolder extends BaseViewHolder {
|
||||
private ImageView icon;
|
||||
private TextView title;
|
||||
private TextView value;
|
||||
private DiscreteSeekBar seekBar;
|
||||
|
||||
|
||||
public BeautyShapeViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.item_icon);
|
||||
title = itemView.findViewById(R.id.item_title);
|
||||
value = itemView.findViewById(R.id.item_value);
|
||||
seekBar = itemView.findViewById(R.id.item_seekBar);
|
||||
seekBar.setOnProgressChangeListener(new DiscreteSeekBar.OnSimpleProgressChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) {
|
||||
super.onProgressChanged(seekBar, value, fromUser);
|
||||
FaceBeautyBean bean = (FaceBeautyBean) itemView.getTag();
|
||||
double toValue = SeekBarUtils.Companion.seekToValue(bean.getModelAttributeData().getMaxRange(), value, seekBar.getMin());
|
||||
BeautyShapeViewHolder.this.value.setTag(String.format("%.1f", toValue));
|
||||
BeautyShapeViewHolder.this.value.setText(value+"");
|
||||
adapter.getFaceBeautyDataFactory().updateParamIntensity(bean.getKey(), toValue);
|
||||
saveData();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageResource(data.getImageRes());
|
||||
title.setText(data.getDesRes());
|
||||
if(loadData()){
|
||||
return;
|
||||
}
|
||||
ModelAttributeData attributeData = data.getModelAttributeData();
|
||||
value.setText(attributeData.getDefault() + "");
|
||||
SeekBarUtils.Companion.seekToSeekBar(seekBar,
|
||||
attributeData.getDefault(),
|
||||
attributeData.getStand(),
|
||||
attributeData.getMaxRange());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
FaceBeautyBean bean = (FaceBeautyBean) itemView.getTag();
|
||||
String val = adapter.getString(getName(this) + bean.getKey());
|
||||
if(val==null) {
|
||||
return false;
|
||||
}
|
||||
ModelAttributeData attributeData = bean.getModelAttributeData();
|
||||
value.setText(val);
|
||||
SeekBarUtils.Companion.seekToSeekBar(seekBar,
|
||||
Double.parseDouble(val),
|
||||
attributeData.getStand(),
|
||||
attributeData.getMaxRange());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
FaceBeautyBean bean = (FaceBeautyBean) itemView.getTag();
|
||||
adapter.save(getName(this)+bean.getKey(), (String) value.getTag());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
String name = getName(this);
|
||||
for (BaseBean bean : list) {
|
||||
adapter.del(name+bean.getKey());
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.seekbar.DiscreteSeekBar;
|
||||
import com.yunbao.faceunity.utils.SeekBarUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 美肤
|
||||
*/
|
||||
public class BeautySkinViewHolder extends BaseViewHolder{
|
||||
private ImageView icon;
|
||||
private TextView title;
|
||||
private TextView value;
|
||||
private DiscreteSeekBar seekBar;
|
||||
|
||||
public BeautySkinViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.item_icon);
|
||||
title = itemView.findViewById(R.id.item_title);
|
||||
value = itemView.findViewById(R.id.item_value);
|
||||
seekBar = itemView.findViewById(R.id.item_seekBar);
|
||||
seekBar.setOnProgressChangeListener(new DiscreteSeekBar.OnSimpleProgressChangeListener(){
|
||||
@Override
|
||||
public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) {
|
||||
super.onProgressChanged(seekBar, value, fromUser);
|
||||
FaceBeautyBean bean = (FaceBeautyBean) itemView.getTag();
|
||||
double toValue = SeekBarUtils.Companion.seekToValue(bean.getModelAttributeData().getMaxRange(), value, seekBar.getMin());
|
||||
BeautySkinViewHolder.this.value.setTag(String.format("%.1f",toValue));
|
||||
BeautySkinViewHolder.this.value.setText(value+"");
|
||||
adapter.getFaceBeautyDataFactory().updateParamIntensity(bean.getKey(),toValue);
|
||||
saveData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageResource(data.getImageRes());
|
||||
title.setText(data.getDesRes());
|
||||
if(loadData()){
|
||||
return;
|
||||
}
|
||||
ModelAttributeData attributeData = data.getModelAttributeData();
|
||||
value.setText(attributeData.getDefault() + "");
|
||||
SeekBarUtils.Companion.seekToSeekBar(seekBar,
|
||||
attributeData.getDefault(),
|
||||
attributeData.getStand(),
|
||||
attributeData.getMaxRange());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
BaseBean data = (FaceBeautyBean) itemView.getTag();
|
||||
ModelAttributeData attributeData = data.getModelAttributeData();
|
||||
String key = getName(this)+data.getKey();
|
||||
String val=adapter.getString(key);
|
||||
if (val==null){
|
||||
return false;
|
||||
}
|
||||
value.setText(val);
|
||||
SeekBarUtils.Companion.seekToSeekBar(seekBar,
|
||||
Double.parseDouble(val),
|
||||
attributeData.getStand(),
|
||||
attributeData.getMaxRange()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
String key = ((FaceBeautyBean)itemView.getTag()).getKey();
|
||||
String val= (String) value.getTag();
|
||||
adapter.save(getName(this)+key,val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
for (BaseBean bean : list) {
|
||||
adapter.del(getName(this)+bean.getKey());
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.FunctionEnum;
|
||||
import com.yunbao.faceunity.entity.PropBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 大头
|
||||
*/
|
||||
public class BigHeadViewHolder extends BaseViewHolder {
|
||||
ImageView icon;
|
||||
|
||||
public BigHeadViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.iv_control);
|
||||
TextView title = itemView.findViewById(R.id.tv_control);
|
||||
title.setVisibility(View.GONE);
|
||||
itemView.setOnClickListener(v -> {
|
||||
PropBean bean = (PropBean) itemView.getTag();
|
||||
adapter.getPropDataFactory().setPropType(FunctionEnum.BIG_HEAD);
|
||||
adapter.getPropDataFactory().onItemSelected(bean);
|
||||
setSelectPosition(getAdapterPosition());
|
||||
saveData();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageResource(data.getImageRes());
|
||||
if(loadData()){
|
||||
return;
|
||||
}
|
||||
|
||||
if (getAdapterPosition() == 0) {
|
||||
icon.setBackgroundResource(R.drawable.bg_control_oval2_selector);
|
||||
}
|
||||
icon.setSelected(getSelectPosition() == getAdapterPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
PropBean bean = (PropBean) itemView.getTag();
|
||||
String val = adapter.getString(getName(this));
|
||||
if(val==null){
|
||||
return false;
|
||||
}
|
||||
if(!val.equals(bean.getKey())){
|
||||
return false;
|
||||
}
|
||||
icon.setSelected(true);
|
||||
adapter.getPropDataFactory().setPropType(FunctionEnum.BIG_HEAD);
|
||||
adapter.getPropDataFactory().onItemSelected(bean);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
PropBean bean = (PropBean) itemView.getTag();
|
||||
adapter.save(getName(this),bean.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
adapter.save(getName(this),list.get(0).getKey());
|
||||
adapter.getPropDataFactory().setPropType(FunctionEnum.BIG_HEAD);
|
||||
adapter.getPropDataFactory().onItemSelected((PropBean) list.get(0));
|
||||
adapter.setSelectPosition(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyFilterBean;
|
||||
import com.yunbao.faceunity.seekbar.DiscreteSeekBar;
|
||||
import com.yunbao.faceunity.utils.SeekBarUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 滤镜
|
||||
*/
|
||||
public class FilterViewHolder extends BaseViewHolder {
|
||||
private ImageView icon;
|
||||
private TextView title;
|
||||
private String KEY_VAL;
|
||||
|
||||
public FilterViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.iv_control);
|
||||
title = itemView.findViewById(R.id.tv_control);
|
||||
itemView.setOnClickListener(view -> {
|
||||
FaceBeautyFilterBean bean = (FaceBeautyFilterBean) itemView.getTag();
|
||||
adapter.getFaceBeautyDataFactory().onFilterSelected(bean.getKey(), bean.getIntensity(), bean.getDesRes());
|
||||
setSelectPosition(getAdapterPosition());
|
||||
saveData();
|
||||
if("origin".equals(bean.getKey())){
|
||||
adapter.hideSeekBar();
|
||||
return;
|
||||
}
|
||||
adapter.showSeekBar();
|
||||
adapter.getSeekBar().setMax(100);
|
||||
adapter.getSeekBar().setTag(bean);
|
||||
adapter.getSeekBar().setOnProgressChangeListener(new DiscreteSeekBar.OnSimpleProgressChangeListener(){
|
||||
@Override
|
||||
public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) {
|
||||
super.onProgressChanged(seekBar, value, fromUser);
|
||||
KEY_VAL=getName(FilterViewHolder.this)+((BaseBean)seekBar.getTag()).getKey()+"_val";
|
||||
double toValue = SeekBarUtils.Companion.seekToValue(1, value, seekBar.getMin());
|
||||
adapter.getFaceBeautyDataFactory().updateFilterIntensity(toValue);
|
||||
adapter.save(KEY_VAL,value+"");
|
||||
}
|
||||
});
|
||||
if(adapter.getString(KEY_VAL)==null) {
|
||||
adapter.getSeekBar().setProgress((int) (bean.getIntensity() * 100));
|
||||
}else{
|
||||
adapter.getSeekBar().setProgress(Integer.parseInt(adapter.getString(KEY_VAL)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageResource(data.getImageRes());
|
||||
title.setText(data.getDesRes());
|
||||
if (loadData()) {
|
||||
return;
|
||||
}
|
||||
icon.setSelected(getSelectPosition() == getAdapterPosition());
|
||||
title.setSelected(getSelectPosition() == getAdapterPosition());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
FaceBeautyFilterBean bean = (FaceBeautyFilterBean) itemView.getTag();
|
||||
KEY_VAL=getName(FilterViewHolder.this)+bean.getKey()+"_val";
|
||||
String val = adapter.getString(getName(this));
|
||||
if (val == null) {
|
||||
return false;
|
||||
}
|
||||
if (!val.equals(bean.getKey())) {
|
||||
return false;
|
||||
}
|
||||
if(!"origin".equals(bean.getKey())){
|
||||
adapter.showSeekBar();
|
||||
}
|
||||
icon.setSelected(true);
|
||||
title.setSelected(true);
|
||||
if(adapter.getString(KEY_VAL)!=null) {
|
||||
bean.setIntensity(Double.parseDouble(adapter.getString(KEY_VAL))/100);
|
||||
}
|
||||
adapter.getFaceBeautyDataFactory().onFilterSelected(bean.getKey(), bean.getIntensity(), bean.getDesRes());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
FaceBeautyFilterBean bean = (FaceBeautyFilterBean) itemView.getTag();
|
||||
adapter.save(getName(this), bean.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
FaceBeautyFilterBean bean = (FaceBeautyFilterBean) list.get(0);
|
||||
for (BaseBean baseBean : list) {
|
||||
String key=getName(this)+baseBean.getKey()+"_val";
|
||||
adapter.save(key,"40");
|
||||
}
|
||||
adapter.hideSeekBar();
|
||||
adapter.save(getName(this),bean.getKey());
|
||||
adapter.getFaceBeautyDataFactory().onFilterSelected(bean.getKey(), bean.getIntensity(), bean.getDesRes());
|
||||
adapter.setSelectPosition(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.common.glide.ImgLoader;
|
||||
import com.yunbao.common.utils.ToastUtil;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.data.FineStickerDataFactory;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.net.FineStickerEntity;
|
||||
import com.yunbao.faceunity.utils.net.StickerDownloadHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 精品贴纸
|
||||
*/
|
||||
public class FineStickerViewHolder extends BaseViewHolder implements StickerDownloadHelper.Callback {
|
||||
ImageView icon;
|
||||
|
||||
public FineStickerViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.iv_control);
|
||||
TextView title = itemView.findViewById(R.id.tv_control);
|
||||
title.setVisibility(View.GONE);
|
||||
itemView.setOnClickListener(view -> {
|
||||
FineStickerDataFactory.getInstance().downloadSticker((FineStickerEntity.DocsBean) itemView.getTag());
|
||||
setSelectPosition(getAdapterPosition());
|
||||
saveData();
|
||||
});
|
||||
FineStickerDataFactory.getInstance().addCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
if (data.getImageUrl().isEmpty()) {
|
||||
icon.setImageResource(R.mipmap.icon_control_none);
|
||||
} else {
|
||||
ImgLoader.display(icon.getContext(), data.getImageUrl(), icon);
|
||||
}
|
||||
if (loadData()) {
|
||||
return;
|
||||
}
|
||||
icon.setSelected(getSelectPosition() == getAdapterPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
FineStickerEntity.DocsBean bean = (FineStickerEntity.DocsBean) itemView.getTag();
|
||||
String val = adapter.getString(getName(this) + bean.getKey());
|
||||
if(val==null){
|
||||
return false;
|
||||
}
|
||||
if(!val.equals(bean.getKey())){
|
||||
return false;
|
||||
}
|
||||
FineStickerDataFactory.getInstance().downloadSticker(bean);
|
||||
icon.setSelected(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
FineStickerEntity.DocsBean bean = (FineStickerEntity.DocsBean) itemView.getTag();
|
||||
adapter.save(getName(this), bean.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
adapter.save(getName(this),list.get(0).getKey());
|
||||
itemView.callOnClick();
|
||||
adapter.setSelectPosition(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetTags(String[] tags) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetList(String tag, FineStickerEntity fineSticker) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownload(FineStickerEntity.DocsBean entity) {
|
||||
FineStickerDataFactory.getInstance().onItemSelected(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadError(FineStickerEntity.DocsBean entity, String msg) {
|
||||
ToastUtil.show("下载失败 = " + msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.MakeupCustomBean;
|
||||
import com.yunbao.faceunity.repo.MakeupSource;
|
||||
import com.yunbao.faceunity.seekbar.DiscreteSeekBar;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 美妆 - 自定义
|
||||
*/
|
||||
public class MakeupCustomItemViewHolder extends BaseViewHolder {
|
||||
private ImageView icon;
|
||||
private TextView title;
|
||||
|
||||
|
||||
public MakeupCustomItemViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.iv_control);
|
||||
title = itemView.findViewById(R.id.tv_control);
|
||||
title.setVisibility(View.INVISIBLE);
|
||||
itemView.setOnClickListener(new View.OnClickListener() {
|
||||
private String key = null;
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
adapter.showSeekBar();
|
||||
MakeupCustomBean bean = (MakeupCustomBean) itemView.getTag();
|
||||
key = getMakeupKey(bean.getBeanType());
|
||||
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
adapter.getMakeupDataFactory().enterCustomMakeup();
|
||||
adapter.getMakeupDataFactory().onCustomBeanSelected(key, getAdapterPosition());
|
||||
adapter.getMakeupDataFactory().bindCurrentRenderer();
|
||||
setSelectPosition(getAdapterPosition());
|
||||
double intensity = adapter.getMakeupDataFactory().getCurrentCustomIntensity(key, adapter.getMakeupDataFactory().getCurrentCustomItemIndex(key));
|
||||
adapter.getSeekBar().setProgress((int) (intensity * 100));
|
||||
adapter.getSeekBar().setOnProgressChangeListener(new DiscreteSeekBar.OnSimpleProgressChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) {
|
||||
super.onProgressChanged(seekBar, value, fromUser);
|
||||
float valueF = (float) (1.0 * (value - seekBar.getMin()) / 100);
|
||||
int current = adapter.getMakeupDataFactory().getCurrentCustomItemIndex(key);
|
||||
adapter.getMakeupDataFactory().updateCustomItemIntensity(key, current, valueF);
|
||||
saveData();
|
||||
}
|
||||
});
|
||||
saveData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageDrawable(data.getImageDrawable());
|
||||
if (loadData()) {
|
||||
return;
|
||||
}
|
||||
if (getSelectPosition() == getAdapterPosition()) {
|
||||
icon.setSelected(true);
|
||||
return;
|
||||
}
|
||||
icon.setSelected(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
MakeupCustomBean bean = (MakeupCustomBean) itemView.getTag();
|
||||
String model = adapter.getString(getName(this));
|
||||
String val = adapter.getString(getName(this) + bean.getKey() + "_val");
|
||||
if (model == null || val == null) {
|
||||
return false;
|
||||
}
|
||||
if(!model.equals(bean.getKey())){
|
||||
return false;
|
||||
}
|
||||
icon.setSelected(true);
|
||||
String key = getMakeupKey(bean.getBeanType());
|
||||
if (key == null) {
|
||||
return false;
|
||||
}
|
||||
adapter.getMakeupDataFactory().enterCustomMakeup();
|
||||
adapter.getMakeupDataFactory().onCustomBeanSelected(key, getAdapterPosition());
|
||||
adapter.getMakeupDataFactory().bindCurrentRenderer();
|
||||
adapter.getSeekBar().setProgress(Integer.parseInt(val));
|
||||
|
||||
float valueF = (float) (1.0 * (Integer.parseInt(val) - adapter.getSeekBar().getMin()) / 100);
|
||||
int current = adapter.getMakeupDataFactory().getCurrentCustomItemIndex(key);
|
||||
adapter.getMakeupDataFactory().updateCustomItemIntensity(key, current, valueF);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
MakeupCustomBean bean = (MakeupCustomBean) itemView.getTag();
|
||||
String key=getMakeupKey(bean.getBeanType());
|
||||
if(key==null){
|
||||
return;
|
||||
}
|
||||
adapter.save(getName(this), key);
|
||||
adapter.save(getName(this) + bean.getKey() + "_val", adapter.getSeekBar().getProgress() + "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
adapter.save(getName(this),list.get(0).getKey());
|
||||
for (BaseBean bean : list) {
|
||||
adapter.del(getName(this) + bean.getKey() + "_val");
|
||||
}
|
||||
adapter.setSelectPosition(0);
|
||||
}
|
||||
|
||||
public String getMakeupKey(int beanType) {
|
||||
String key = null;
|
||||
switch (beanType) {
|
||||
case FaceParam.FACE_MAKEUP_TYPE_FOUNDATION:
|
||||
key = MakeupSource.FACE_MAKEUP_TYPE_FOUNDATION;
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_LIP_STICK:
|
||||
key = MakeupSource.FACE_MAKEUP_TYPE_LIP_STICK;
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_BLUSHER:
|
||||
key = MakeupSource.FACE_MAKEUP_TYPE_BLUSHER;
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_BROW:
|
||||
key = MakeupSource.FACE_MAKEUP_TYPE_EYE_BROW;
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW:
|
||||
key = MakeupSource.FACE_MAKEUP_TYPE_EYE_SHADOW;
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_LINER:
|
||||
key = MakeupSource.FACE_MAKEUP_TYPE_EYE_LINER;
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_LASH:
|
||||
key = MakeupSource.FACE_MAKEUP_TYPE_EYE_LASH;
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_HIGH_LIGHT:
|
||||
key = MakeupSource.FACE_MAKEUP_TYPE_HIGH_LIGHT;
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_SHADOW:
|
||||
key = MakeupSource.FACE_MAKEUP_TYPE_SHADOW;
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL:
|
||||
key = MakeupSource.FACE_MAKEUP_TYPE_EYE_PUPIL;
|
||||
break;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.MakeupCombinationBean;
|
||||
import com.yunbao.faceunity.utils.FaceSPUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 美妆
|
||||
*/
|
||||
public class MakeupViewHolder extends BaseViewHolder {
|
||||
private ImageView icon;
|
||||
private TextView title;
|
||||
|
||||
public MakeupViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon = itemView.findViewById(R.id.iv_control);
|
||||
title = itemView.findViewById(R.id.tv_control);
|
||||
itemView.setOnClickListener(v -> {
|
||||
adapter.getMakeupDataFactory().onMakeupCombinationSelected((MakeupCombinationBean) itemView.getTag());
|
||||
setSelectPosition(getAdapterPosition());
|
||||
saveData();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageResource(data.getImageRes());
|
||||
title.setText(data.getDesRes());
|
||||
if(loadData()){
|
||||
return;
|
||||
}
|
||||
if (getSelectPosition() == getAdapterPosition()) {
|
||||
icon.setSelected(true);
|
||||
title.setSelected(true);
|
||||
return;
|
||||
}
|
||||
icon.setSelected(false);
|
||||
title.setSelected(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
MakeupCombinationBean bean = (MakeupCombinationBean) itemView.getTag();
|
||||
String val = adapter.getString(getName(this));
|
||||
if(val==null){
|
||||
return false;
|
||||
}
|
||||
if(!val.equals(bean.getKey())){
|
||||
return false;
|
||||
}
|
||||
icon.setSelected(true);
|
||||
title.setSelected(true);
|
||||
adapter.getMakeupDataFactory().onMakeupCombinationSelected(bean);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
MakeupCombinationBean bean = (MakeupCombinationBean) itemView.getTag();
|
||||
adapter.save(getName(this),bean.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean>list) {
|
||||
adapter.save(getName(this),list.get(0).getKey());
|
||||
FaceSPUtils.getInstance().delStart("MakeupCustomItemViewHolder");
|
||||
adapter.getMakeupDataFactory().onMakeupCombinationSelected((MakeupCombinationBean) list.get(0));
|
||||
adapter.getMakeupDataFactory().clearAll();
|
||||
adapter.setSelectPosition(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.FunctionEnum;
|
||||
import com.yunbao.faceunity.entity.PropBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 普通贴纸
|
||||
*/
|
||||
public class StickerViewHolder extends BaseViewHolder{
|
||||
ImageView icon;
|
||||
public StickerViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon =itemView.findViewById(R.id.iv_control);
|
||||
TextView title = itemView.findViewById(R.id.tv_control);
|
||||
title.setVisibility(View.GONE);
|
||||
itemView.setOnClickListener(v -> {
|
||||
PropBean bean= (PropBean) itemView.getTag();
|
||||
adapter.getPropDataFactory().setPropType(FunctionEnum.STICKER);
|
||||
adapter.getPropDataFactory().onItemSelected(bean);
|
||||
setSelectPosition(getAdapterPosition());
|
||||
saveData();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageResource(data.getImageRes());
|
||||
if(loadData()){
|
||||
return;
|
||||
}
|
||||
if(getAdapterPosition()==0){
|
||||
icon.setBackgroundResource(R.drawable.bg_control_oval2_selector);
|
||||
}
|
||||
icon.setSelected(getSelectPosition() == getAdapterPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
PropBean bean= (PropBean) itemView.getTag();
|
||||
String val = adapter.getString(getName(this));
|
||||
if(val==null){
|
||||
return false;
|
||||
}
|
||||
if(!val.equals(bean.getKey())){
|
||||
return false;
|
||||
}
|
||||
icon.setSelected(true);
|
||||
adapter.getPropDataFactory().setPropType(FunctionEnum.STICKER);
|
||||
adapter.getPropDataFactory().onItemSelected(bean);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
PropBean bean= (PropBean) itemView.getTag();
|
||||
adapter.save(getName(this),bean.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
adapter.save(getName(this),list.get(0).getKey());
|
||||
adapter.getPropDataFactory().setPropType(FunctionEnum.STICKER);
|
||||
adapter.getPropDataFactory().onItemSelected((PropBean) list.get(0));
|
||||
adapter.setSelectPosition(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.yunbao.faceunity.adapters.vh;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 风格推荐
|
||||
*/
|
||||
public class StyleViewHolder extends BaseViewHolder{
|
||||
private ImageView icon;
|
||||
private TextView title;
|
||||
public StyleViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
icon=itemView.findViewById(R.id.iv_control);
|
||||
title=itemView.findViewById(R.id.tv_control);
|
||||
itemView.setOnClickListener(v -> {
|
||||
BaseBean bean= (BaseBean) itemView.getTag();
|
||||
adapter.getFaceBeautyDataFactory().onStyleSelected(bean.getKey());
|
||||
setSelectPosition(getAdapterPosition());
|
||||
saveData();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(BaseBean data) {
|
||||
itemView.setTag(data);
|
||||
icon.setImageResource(data.getImageRes());
|
||||
title.setText(data.getDesRes());
|
||||
if(loadData()){
|
||||
return;
|
||||
}
|
||||
icon.setSelected(getSelectPosition()==getAdapterPosition());
|
||||
title.setSelected(getSelectPosition()==getAdapterPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadData() {
|
||||
BaseBean bean= (BaseBean) itemView.getTag();
|
||||
String val = adapter.getString(getName(this));
|
||||
if(val==null){
|
||||
icon.setSelected(false);
|
||||
title.setSelected(false);
|
||||
return true;
|
||||
}
|
||||
if(!val.equals(bean.getKey())){
|
||||
return false;
|
||||
}
|
||||
icon.setSelected(true);
|
||||
title.setSelected(true);
|
||||
adapter.getFaceBeautyDataFactory().onStyleSelected(bean.getKey());
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
BaseBean bean= (BaseBean) itemView.getTag();
|
||||
adapter.save(getName(this),bean.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<? extends BaseBean> list) {
|
||||
// adapter.save(getName(this),list.get(0).getKey());
|
||||
adapter.setSelectPosition(0);
|
||||
adapter.del(getName(this));
|
||||
adapter.getFaceBeautyDataFactory().onStyleSelected(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.yunbao.faceunity.checkbox;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.StateListDrawable;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatCheckBox;
|
||||
|
||||
|
||||
/**
|
||||
* 解决 RadioButton 在 Android4.4 调用setButtonDrawable(null) 和 XML 设置 android:button="@null"无效的问题
|
||||
*
|
||||
* @author Richie on 2020.05.18
|
||||
*/
|
||||
public class CheckBoxCompat extends AppCompatCheckBox {
|
||||
|
||||
public CheckBoxCompat(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public CheckBoxCompat(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public CheckBoxCompat(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setButtonDrawable(new StateListDrawable());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
package com.yunbao.faceunity.checkbox;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.IdRes;
|
||||
|
||||
/**
|
||||
* Created by tujh on 2018/4/17.
|
||||
*/
|
||||
public class CheckGroup extends LinearLayout {
|
||||
private static final String LOG_TAG = CheckGroup.class.getSimpleName();
|
||||
|
||||
// holds the checked id; the selection is empty by default
|
||||
private int mCheckedId = View.NO_ID;
|
||||
// tracks children radio buttons checked state
|
||||
private CompoundButton.OnCheckedChangeListener mChildOnCheckedChangeListener;
|
||||
// when true, mOnCheckedChangeListener discards events
|
||||
private boolean mProtectFromCheckedChange = false;
|
||||
private OnCheckedChangeListener mOnCheckedChangeListener;
|
||||
private PassThroughHierarchyChangeListener mPassThroughListener;
|
||||
private OnDispatchActionUpListener mOnDispatchActionUpListener;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public CheckGroup(Context context) {
|
||||
super(context);
|
||||
setOrientation(VERTICAL);
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public CheckGroup(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mChildOnCheckedChangeListener = new CheckedStateTracker();
|
||||
mPassThroughListener = new PassThroughHierarchyChangeListener();
|
||||
super.setOnHierarchyChangeListener(mPassThroughListener);
|
||||
}
|
||||
|
||||
public void setOnDispatchActionUpListener(OnDispatchActionUpListener onDispatchActionUpListener) {
|
||||
mOnDispatchActionUpListener = onDispatchActionUpListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) {
|
||||
// the user listener is delegated to our pass-through listener
|
||||
mPassThroughListener.mOnHierarchyChangeListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_UP) {
|
||||
if (mOnDispatchActionUpListener != null) {
|
||||
mOnDispatchActionUpListener.onDispatchActionUp((int) ev.getX());
|
||||
}
|
||||
}
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
// checks the appropriate radio button as requested in the XML file
|
||||
if (mCheckedId != View.NO_ID) {
|
||||
mProtectFromCheckedChange = true;
|
||||
setCheckedStateForView(mCheckedId, true);
|
||||
mProtectFromCheckedChange = false;
|
||||
setCheckedId(mCheckedId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
||||
if (child instanceof CheckBox) {
|
||||
final CheckBox button = (CheckBox) child;
|
||||
if (button.isChecked()) {
|
||||
mProtectFromCheckedChange = true;
|
||||
if (mCheckedId != View.NO_ID) {
|
||||
setCheckedStateForView(mCheckedId, false);
|
||||
}
|
||||
mProtectFromCheckedChange = false;
|
||||
setCheckedId(button.getId());
|
||||
}
|
||||
}
|
||||
|
||||
super.addView(child, index, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the selection to the radio button whose identifier is passed in
|
||||
* parameter. Using View.NO_ID as the selection identifier clears the selection;
|
||||
* such an operation is equivalent to invoking {@link #clearCheck()}.</p>
|
||||
*
|
||||
* @param id the unique id of the radio button to select in this group
|
||||
* @see #getCheckedCheckBoxId()
|
||||
* @see #clearCheck()
|
||||
*/
|
||||
public void check(@IdRes int id) {
|
||||
// don't even bother
|
||||
if (id != View.NO_ID && (id == mCheckedId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCheckedId != View.NO_ID) {
|
||||
setCheckedStateForView(mCheckedId, false);
|
||||
}
|
||||
|
||||
if (id != View.NO_ID) {
|
||||
setCheckedStateForView(id, true);
|
||||
}
|
||||
|
||||
setCheckedId(id);
|
||||
}
|
||||
|
||||
private void setCheckedId(@IdRes int id) {
|
||||
mCheckedId = id;
|
||||
if (mOnCheckedChangeListener != null) {
|
||||
mOnCheckedChangeListener.onCheckedChanged(this, mCheckedId);
|
||||
}
|
||||
}
|
||||
|
||||
private void setCheckedStateForView(int viewId, boolean checked) {
|
||||
View checkedView = findViewById(viewId);
|
||||
if (checkedView != null && checkedView instanceof CheckBox) {
|
||||
((CheckBox) checkedView).setChecked(checked);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the identifier of the selected radio button in this group.
|
||||
* Upon empty selection, the returned value is View.NO_ID.</p>
|
||||
*
|
||||
* @return the unique id of the selected radio button in this group
|
||||
* @attr ref android.R.styleable#CheckGroup_checkedButton
|
||||
* @see #check(int)
|
||||
* @see #clearCheck()
|
||||
*/
|
||||
@IdRes
|
||||
public int getCheckedCheckBoxId() {
|
||||
return mCheckedId;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Clears the selection. When the selection is cleared, no radio button
|
||||
* in this group is selected and {@link #getCheckedCheckBoxId()} returns
|
||||
* null.</p>
|
||||
*
|
||||
* @see #check(int)
|
||||
* @see #getCheckedCheckBoxId()
|
||||
*/
|
||||
public void clearCheck() {
|
||||
check(View.NO_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Register a callback to be invoked when the checked radio button
|
||||
* changes in this group.</p>
|
||||
*
|
||||
* @param listener the callback to call on checked state change
|
||||
*/
|
||||
public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
|
||||
mOnCheckedChangeListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getAccessibilityClassName() {
|
||||
return CheckGroup.class.getName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Interface definition for a callback to be invoked when the checked
|
||||
* radio button changed in this group.</p>
|
||||
*/
|
||||
public interface OnCheckedChangeListener {
|
||||
/**
|
||||
* <p>Called when the checked radio button has changed. When the
|
||||
* selection is cleared, checkedId is View.NO_ID.</p>
|
||||
*
|
||||
* @param group the group in which the checked radio button has changed
|
||||
* @param checkedId the unique identifier of the newly checked radio button
|
||||
*/
|
||||
public void onCheckedChanged(CheckGroup group, @IdRes int checkedId);
|
||||
}
|
||||
|
||||
private class CheckedStateTracker implements CompoundButton.OnCheckedChangeListener {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
// prevents from infinite recursion
|
||||
if (mProtectFromCheckedChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
int id = buttonView.getId();
|
||||
mProtectFromCheckedChange = true;
|
||||
if (mCheckedId != View.NO_ID && mCheckedId != id) {
|
||||
setCheckedStateForView(mCheckedId, false);
|
||||
}
|
||||
mProtectFromCheckedChange = false;
|
||||
|
||||
setCheckedId(isChecked ? id : View.NO_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>A pass-through listener acts upon the events and dispatches them
|
||||
* to another listener. This allows the table layout to set its own internal
|
||||
* hierarchy change listener without preventing the user to setup his.</p>
|
||||
*/
|
||||
private class PassThroughHierarchyChangeListener implements
|
||||
OnHierarchyChangeListener {
|
||||
private OnHierarchyChangeListener mOnHierarchyChangeListener;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onChildViewAdded(View parent, View child) {
|
||||
if (parent == CheckGroup.this && child instanceof CheckBox) {
|
||||
int id = child.getId();
|
||||
// generates an id if it's missing
|
||||
if (id == View.NO_ID) {
|
||||
id = View.generateViewId();
|
||||
child.setId(id);
|
||||
}
|
||||
((CheckBox) child).setOnCheckedChangeListener(
|
||||
mChildOnCheckedChangeListener);
|
||||
}
|
||||
|
||||
if (mOnHierarchyChangeListener != null) {
|
||||
mOnHierarchyChangeListener.onChildViewAdded(parent, child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onChildViewRemoved(View parent, View child) {
|
||||
if (parent == CheckGroup.this && child instanceof CheckBox) {
|
||||
((CheckBox) child).setOnCheckedChangeListener(null);
|
||||
}
|
||||
|
||||
if (mOnHierarchyChangeListener != null) {
|
||||
mOnHierarchyChangeListener.onChildViewRemoved(parent, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnDispatchActionUpListener {
|
||||
/**
|
||||
* 分发 action up 事件时回调
|
||||
*
|
||||
* @param x
|
||||
*/
|
||||
void onDispatchActionUp(int x);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.animationFilter.AnimationFilter;
|
||||
import com.faceunity.core.model.antialiasing.Antialiasing;
|
||||
import com.faceunity.core.model.prop.Prop;
|
||||
import com.faceunity.core.model.prop.PropContainer;
|
||||
import com.faceunity.core.model.prop.animoji.Animoji;
|
||||
import com.yunbao.faceunity.entity.AnimationFilterBean;
|
||||
import com.yunbao.faceunity.entity.AnimojiBean;
|
||||
import com.yunbao.faceunity.infe.AbstractAnimojiDataFactory;
|
||||
import com.yunbao.faceunity.repo.AnimojiSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DESC:Animoji业务工厂
|
||||
* Created on 2021/3/3
|
||||
*/
|
||||
public class AnimojiDataFactory extends AbstractAnimojiDataFactory {
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
private FUAIKit mFUAIKit = FUAIKit.getInstance();
|
||||
/*3D抗锯齿*/
|
||||
public final Antialiasing antialiasing;
|
||||
/*动漫滤镜模型*/
|
||||
public final AnimationFilter animationFilter;
|
||||
/*当前选中贴图模型*/
|
||||
private Prop currentAnimoji;
|
||||
/*当前选中下标*/
|
||||
private int currentAnimojiIndex;
|
||||
/*当前滤镜下标*/
|
||||
private int currentFilterIndex;
|
||||
/*Animoji数据*/
|
||||
private ArrayList<AnimojiBean> animojiBeans;
|
||||
/*Animoji滤镜数据*/
|
||||
private ArrayList<AnimationFilterBean> animationFilterBeans;
|
||||
|
||||
/**
|
||||
* 构造 AnimojiDataFactory
|
||||
*
|
||||
* @param animojiIndex 贴图下标
|
||||
* @param filterIndex 滤镜下标
|
||||
*/
|
||||
public AnimojiDataFactory(int animojiIndex, int filterIndex) {
|
||||
antialiasing = new Antialiasing(new FUBundleData(FaceUnityConfig.BUNDLE_ANTI_ALIASING));
|
||||
animationFilter = new AnimationFilter(new FUBundleData(FaceUnityConfig.BUNDLE_ANIMATION_FILTER));
|
||||
currentAnimojiIndex = animojiIndex;
|
||||
currentFilterIndex = filterIndex;
|
||||
animojiBeans = AnimojiSource.buildAnimojis();
|
||||
animationFilterBeans = AnimojiSource.buildFilters();
|
||||
bindCurrentRenderer();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 动漫贴图列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<AnimojiBean> getAnimojis() {
|
||||
return animojiBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 动漫滤镜列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<AnimationFilterBean> getFilters() {
|
||||
return animationFilterBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前选中动漫贴图下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentAnimojiIndex() {
|
||||
return currentAnimojiIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前选中动漫贴图下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentAnimojiIndex(int currentAnimojiIndex) {
|
||||
this.currentAnimojiIndex = currentAnimojiIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前选中滤镜下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentFilterIndex() {
|
||||
return currentFilterIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前选中动漫贴图下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentFilterIndex(int currentFilterIndex) {
|
||||
this.currentFilterIndex = currentFilterIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置选中贴图
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void onAnimojiSelected(AnimojiBean bean) {
|
||||
PropContainer propContainer = mFURenderKit.getPropContainer();
|
||||
String path = bean.getPath();
|
||||
Prop prop = null;
|
||||
if (path != null && path.trim().length() > 0) {
|
||||
prop = new Animoji(new FUBundleData(path));
|
||||
}
|
||||
propContainer.replaceProp(currentAnimoji, prop);
|
||||
currentAnimoji = prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置选中滤镜
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
@Override
|
||||
public void onFilterSelected(AnimationFilterBean data) {
|
||||
|
||||
animationFilter.setStyle(data.getStyle());
|
||||
}
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFUAIKit.loadAIProcessor(FaceUnityConfig.BUNDLE_AI_TONGUE, FUAITypeEnum.FUAITYPE_TONGUETRACKING);
|
||||
mFUAIKit.setMaxFaces(4);
|
||||
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
mFURenderKit.setAntialiasing(antialiasing);
|
||||
mFURenderKit.setAnimationFilter(animationFilter);
|
||||
animationFilter.setStyle(animationFilterBeans.get(currentFilterIndex).getStyle());
|
||||
onAnimojiSelected(animojiBeans.get(currentAnimojiIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束需要释放AI驱动
|
||||
*/
|
||||
public void releaseAIProcessor() {
|
||||
mFUAIKit.releaseAIProcessor(FUAITypeEnum.FUAITYPE_TONGUETRACKING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import com.faceunity.core.avatar.model.Avatar;
|
||||
import com.faceunity.core.avatar.model.Scene;
|
||||
import com.faceunity.core.avatar.scene.ProcessorConfig;
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.entity.FUCoordinate3DData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.faceunity.FUSceneKit;
|
||||
import com.faceunity.core.model.antialiasing.Antialiasing;
|
||||
import com.yunbao.faceunity.entity.AvatarBean;
|
||||
import com.yunbao.faceunity.infe.AbstractAvatarDataFactory;
|
||||
import com.yunbao.faceunity.repo.AvatarSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DESC:
|
||||
* Created on 2021/3/30
|
||||
*/
|
||||
public class AvatarDataFactory extends AbstractAvatarDataFactory {
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
private FUAIKit mFUAIKit = FUAIKit.getInstance();
|
||||
/*3D抗锯齿*/
|
||||
public final Antialiasing antialiasing;
|
||||
|
||||
/* 人物队列 */
|
||||
private ArrayList<AvatarBean> members;
|
||||
/* 当前选中人物下标 */
|
||||
private int currentMemberIndex;
|
||||
/* 驱动类型是否为全身 */
|
||||
private Boolean isHumanTrackSceneFull;
|
||||
|
||||
/* 场景 */
|
||||
private Scene sceneModel;
|
||||
/* 男孩对象 */
|
||||
private Avatar boyAvatarModel;
|
||||
/* 女孩对象 */
|
||||
private Avatar girlAvatarModel;
|
||||
/*当前对象*/
|
||||
private Avatar currentAvatarModel;
|
||||
|
||||
|
||||
public AvatarDataFactory(int index, boolean isFull) {
|
||||
isHumanTrackSceneFull = isFull;
|
||||
currentMemberIndex = index;
|
||||
members = AvatarSource.buildMembers();
|
||||
antialiasing = new Antialiasing(new FUBundleData(FaceUnityConfig.BUNDLE_ANTI_ALIASING));
|
||||
boyAvatarModel = AvatarSource.buildBoyData(isFull);
|
||||
girlAvatarModel = AvatarSource.buildGirlData(isFull);
|
||||
|
||||
if (index == 0) {
|
||||
currentAvatarModel = girlAvatarModel;
|
||||
} else if (index == 1) {
|
||||
currentAvatarModel = boyAvatarModel;
|
||||
}
|
||||
|
||||
sceneModel = AvatarSource.buildSceneModel(currentAvatarModel);
|
||||
AvatarSource.setSceneBackGround(sceneModel, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取人物队列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<AvatarBean> getMembers() {
|
||||
return members;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前选中人物下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentMemberIndex() {
|
||||
return currentMemberIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前人物选中下标
|
||||
*
|
||||
* @param index
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentMemberIndex(int index) {
|
||||
currentMemberIndex = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前驱动类型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean isHumanTrackSceneFull() {
|
||||
return isHumanTrackSceneFull;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前驱动类型
|
||||
*
|
||||
* @param isFull
|
||||
*/
|
||||
@Override
|
||||
public void setHumanTrackSceneFull(boolean isFull) {
|
||||
isHumanTrackSceneFull = isFull;
|
||||
sceneModel.processorConfig.setTrackScene(isFull ? ProcessorConfig.TrackScene.SceneFull : ProcessorConfig.TrackScene.SceneHalf);
|
||||
if (isFull) {
|
||||
boyAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 58.14, -618.94));
|
||||
girlAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 58.14, -618.94));
|
||||
} else {
|
||||
boyAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 11.76, -183.89));
|
||||
girlAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 11.76, -183.89));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 人物切换
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void onMemberSelected(AvatarBean bean) {
|
||||
if (mAvatarChoiceListener != null)
|
||||
mAvatarChoiceListener.choiceAvatar(bean);
|
||||
|
||||
sceneModel.replaceAvatar(currentAvatarModel, bean.getDes().equals(AvatarSource.GIRL) ? girlAvatarModel : boyAvatarModel);
|
||||
currentAvatarModel = bean.getDes().equals(AvatarSource.GIRL) ? girlAvatarModel : boyAvatarModel;
|
||||
}
|
||||
|
||||
public void bindCurrentRenderer() {
|
||||
mFUAIKit.loadAIProcessor(FaceUnityConfig.getAIHumanBundle(), FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
mFUAIKit.setMaxFaces(1);
|
||||
mFURenderKit.setAntialiasing(antialiasing);
|
||||
FUSceneKit.getInstance().addSceneGL(sceneModel);
|
||||
FUSceneKit.getInstance().setCurrentSceneGL(sceneModel);
|
||||
setHumanTrackSceneFull(isHumanTrackSceneFull);
|
||||
}
|
||||
|
||||
public AvatarChoiceListener mAvatarChoiceListener;
|
||||
|
||||
public interface AvatarChoiceListener {
|
||||
void choiceAvatar(AvatarBean avatarBean);
|
||||
}
|
||||
|
||||
public void setAvatarChoiceListener(AvatarChoiceListener avatarChoiceListener) {
|
||||
this.mAvatarChoiceListener = avatarChoiceListener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.faceunity.core.controller.bgSegGreen.BgSegGreenParam;
|
||||
import com.faceunity.core.entity.FUColorRGBData;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.bgSegGreen.BgSegGreen;
|
||||
import com.yunbao.faceunity.entity.BgSegGreenBackgroundBean;
|
||||
import com.yunbao.faceunity.entity.BgSegGreenBean;
|
||||
import com.yunbao.faceunity.entity.BgSegGreenSafeAreaBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.infe.AbstractBgSegGreenDataFactory;
|
||||
import com.yunbao.faceunity.repo.BgSegGreenSource;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* DESC:绿幕抠像业务工厂
|
||||
* Created on 2021/3/4
|
||||
*/
|
||||
public class BgSegGreenDataFactory extends AbstractBgSegGreenDataFactory {
|
||||
public interface BgSegGreenListener {
|
||||
/**
|
||||
* 取色状态回调
|
||||
*
|
||||
* @param isSelected 是否选中
|
||||
* @param color 默认颜色
|
||||
*/
|
||||
void onColorPickerStateChanged(boolean isSelected, int color);
|
||||
|
||||
/**
|
||||
* 切换背景道具
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
void onBackgroundSelected(BgSegGreenBackgroundBean bean);
|
||||
|
||||
/**
|
||||
* 添加自定义安全区域图片
|
||||
*/
|
||||
void onSafeAreaAdd();
|
||||
|
||||
/**
|
||||
* 切换安全区域图片
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
void onSafeAreaSelected(BgSegGreenSafeAreaBean bean);
|
||||
}
|
||||
|
||||
|
||||
/*渲染控制器*/
|
||||
private final FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
|
||||
/*绿幕抠像特效模型*/
|
||||
private final BgSegGreen mBgSegGreen;
|
||||
|
||||
/*绿幕抠像背景列表*/
|
||||
private final ArrayList<BgSegGreenBackgroundBean> mBgSegGreenBackgroundBeans;
|
||||
/* 绿幕抠像当前背景下标 */
|
||||
private int mCurrentBackgroundIndex;
|
||||
|
||||
/*绿幕抠像安全区域列表*/
|
||||
private ArrayList<BgSegGreenSafeAreaBean> mBgSegGreenSafeAreaBeans;
|
||||
/* 绿幕抠像当前安全区域下标 */
|
||||
private int mCurrentSafeAreaIndex;
|
||||
|
||||
/* 回调 */
|
||||
private final BgSegGreenListener mBgSegGreenListener;
|
||||
|
||||
|
||||
/**
|
||||
* 构造绿幕抠像
|
||||
*
|
||||
* @param listener 回调
|
||||
* @param index 背景下标
|
||||
*/
|
||||
public BgSegGreenDataFactory(BgSegGreenListener listener, int index) {
|
||||
mBgSegGreenListener = listener;
|
||||
mBgSegGreen = BgSegGreenSource.buildBgSegGreen();
|
||||
mBgSegGreenBackgroundBeans = BgSegGreenSource.buildBgSegGreenBackground();
|
||||
mBgSegGreenSafeAreaBeans = BgSegGreenSource.buildBgSegGreenSafeArea();
|
||||
mCurrentBackgroundIndex = index;
|
||||
mCurrentSafeAreaIndex = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像当前背景下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
|
||||
public int getBackgroundIndex() {
|
||||
return mCurrentBackgroundIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置绿幕抠像当前背景下标
|
||||
*
|
||||
* @param backgroundIndex
|
||||
*/
|
||||
@Override
|
||||
public void setBackgroundIndex(int backgroundIndex) {
|
||||
this.mCurrentBackgroundIndex = backgroundIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像当前安全区域下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getBgSafeAreaIndex() {
|
||||
return mCurrentSafeAreaIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置绿幕抠像安全区域下标
|
||||
*
|
||||
* @param currentSafeAreaIndex
|
||||
*/
|
||||
@Override
|
||||
public void setBgSafeAreaIndex(int currentSafeAreaIndex) {
|
||||
this.mCurrentSafeAreaIndex = currentSafeAreaIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新安全区UI
|
||||
*/
|
||||
public boolean updateSafeAreaBeansAndIndex() {
|
||||
ArrayList<BgSegGreenSafeAreaBean> bgSegGreenSafeAreaBeans = BgSegGreenSource.buildBgSegGreenSafeArea();
|
||||
if (!bgSegGreenSafeAreaBeans.equals(mBgSegGreenSafeAreaBeans)) {
|
||||
//需要刷新数据
|
||||
//比对数据 1、数据增加 or 自定义数据修改 -> 当前应该选中的角标
|
||||
if (bgSegGreenSafeAreaBeans.size() > mBgSegGreenSafeAreaBeans.size()) {
|
||||
//数据增加
|
||||
if (mCurrentSafeAreaIndex > 2) {
|
||||
mCurrentSafeAreaIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
mBgSegGreenSafeAreaBeans = bgSegGreenSafeAreaBeans;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像项目数据扩展模型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public HashMap<String, ModelAttributeData> getModelAttributeRange() {
|
||||
return BgSegGreenSource.buildModelAttributeRange();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像功能列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<BgSegGreenBean> getBgSegGreenActions() {
|
||||
return BgSegGreenSource.buildBgSegGreenAction();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像安全区域功能列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<BgSegGreenSafeAreaBean> getBgSegGreenSafeAreas() {
|
||||
return mBgSegGreenSafeAreaBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像背景列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<BgSegGreenBackgroundBean> getBgSegGreenBackgrounds() {
|
||||
return mBgSegGreenBackgroundBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 背景图片变更
|
||||
*
|
||||
* @param data BgSegGreenBackgroundBean
|
||||
*/
|
||||
@Override
|
||||
public void onBackgroundSelected(BgSegGreenBackgroundBean data) {
|
||||
mBgSegGreenListener.onBackgroundSelected(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义安全区域
|
||||
*/
|
||||
@Override
|
||||
public void onSafeAreaAdd() {
|
||||
mBgSegGreenListener.onSafeAreaAdd();
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全区域变更
|
||||
*
|
||||
* @param data BgSegGreenBackgroundBean
|
||||
*/
|
||||
@Override
|
||||
public void onSafeAreaSelected(BgSegGreenSafeAreaBean data) {
|
||||
mBgSegGreenListener.onSafeAreaSelected(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseTemplate() {
|
||||
return getCurrentBgSegGreenModel().isUseTemplate() == 1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取色锚点颜色变更
|
||||
*
|
||||
* @param array DoubleArray
|
||||
*/
|
||||
@Override
|
||||
public void onColorRGBChanged(double[] array) {
|
||||
mBgSegGreen.setColorRGB(new FUColorRGBData(array[0], array[1], array[2]));
|
||||
mBgSegGreen.setEnable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绿幕开关
|
||||
*
|
||||
* @param enable Boolean
|
||||
*/
|
||||
@Override
|
||||
public void onBgSegGreenEnableChanged(boolean enable) {
|
||||
mBgSegGreen.setEnable(enable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据名称标识获取对应的值
|
||||
*
|
||||
* @param key String 标识
|
||||
* @return Double 值
|
||||
*/
|
||||
@Override
|
||||
public double getParamIntensity(@NonNull String key) {
|
||||
if (bgSegGreenGetMapping.containsKey(key)) {
|
||||
return bgSegGreenGetMapping.get(key).getValue();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据名称标识更新对应的值
|
||||
*
|
||||
* @param key String 标识
|
||||
* @return Double 值
|
||||
*/
|
||||
@Override
|
||||
public void updateParamIntensity(@NonNull String key, double value) {
|
||||
if (bgSegGreenSetMapping.containsKey(key)) {
|
||||
Objects.requireNonNull(bgSegGreenSetMapping.get(key)).setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用取色器功能状态变更
|
||||
*
|
||||
* @param selected
|
||||
* @param color
|
||||
*/
|
||||
@Override
|
||||
public void onColorPickerStateChanged(boolean selected, int color) {
|
||||
mBgSegGreenListener.onColorPickerStateChanged(selected, color);
|
||||
}
|
||||
|
||||
//region 业务映射
|
||||
|
||||
/**
|
||||
* 参数设置
|
||||
*/
|
||||
interface BgSegGreenSetParam {
|
||||
void setValue(double value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型参数获取
|
||||
*/
|
||||
interface BgSegGreenGetParam {
|
||||
double getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前绿幕对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private BgSegGreen getCurrentBgSegGreenModel() {
|
||||
return mBgSegGreen;
|
||||
}
|
||||
|
||||
|
||||
/* 模型映射 */
|
||||
private final HashMap<String, BgSegGreenSetParam> bgSegGreenSetMapping = new HashMap<String, BgSegGreenSetParam>() {
|
||||
{
|
||||
put(BgSegGreenParam.SIMILARITY, value -> getCurrentBgSegGreenModel().setSimilarity(value));
|
||||
put(BgSegGreenParam.SMOOTHNESS, value -> getCurrentBgSegGreenModel().setSmoothness(value));
|
||||
put(BgSegGreenParam.TRANSPARENCY, value -> getCurrentBgSegGreenModel().setTransparency(value));
|
||||
}
|
||||
};
|
||||
|
||||
/*模型映射获取模型值*/
|
||||
private final HashMap<String, BgSegGreenGetParam> bgSegGreenGetMapping = new HashMap<String, BgSegGreenGetParam>() {
|
||||
{
|
||||
put(BgSegGreenParam.SIMILARITY, () -> getCurrentBgSegGreenModel().getSimilarity());
|
||||
put(BgSegGreenParam.SMOOTHNESS, () -> getCurrentBgSegGreenModel().getSmoothness());
|
||||
put(BgSegGreenParam.TRANSPARENCY, () -> getCurrentBgSegGreenModel().getTransparency());
|
||||
}
|
||||
};
|
||||
|
||||
//endregion 业务映射
|
||||
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
FUAIKit.getInstance().setMaxFaces(1);
|
||||
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
mFURenderKit.setBgSegGreen(mBgSegGreen);
|
||||
mBgSegGreenListener.onBackgroundSelected(mBgSegGreenBackgroundBeans.get(mCurrentBackgroundIndex));
|
||||
mBgSegGreenListener.onSafeAreaSelected(mBgSegGreenSafeAreaBeans.get(mCurrentSafeAreaIndex));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import com.faceunity.core.controller.bodyBeauty.BodyBeautyParam;
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.bodyBeauty.BodyBeauty;
|
||||
|
||||
import com.yunbao.faceunity.entity.BodyBeautyBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.infe.AbstractBodyBeautyDataFactory;
|
||||
import com.yunbao.faceunity.repo.BodyBeautySource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* DESC:美体业务工厂
|
||||
* Created on 2021/3/2
|
||||
*/
|
||||
public class BodyBeautyDataFactory extends AbstractBodyBeautyDataFactory {
|
||||
|
||||
|
||||
interface BodyBeautySetParamInterface {
|
||||
void setValue(double value);
|
||||
}
|
||||
|
||||
interface BodyBeautyGetParamInterface {
|
||||
double getValue();
|
||||
}
|
||||
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
private FUAIKit mFUAIKit = FUAIKit.getInstance();
|
||||
|
||||
/*美体数据模型*/
|
||||
public final BodyBeauty bodyBeauty;
|
||||
|
||||
public BodyBeautyDataFactory() {
|
||||
bodyBeauty = new BodyBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_BODY_BEAUTY));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取美体属性列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<BodyBeautyBean> getBodyBeautyParam() {
|
||||
return BodyBeautySource.buildBodyBeauty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取美体扩展参数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public HashMap<String, ModelAttributeData> getModelAttributeRange() {
|
||||
return BodyBeautySource.buildModelAttributeRange();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取模型参数
|
||||
*
|
||||
* @param key 名称标识
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double getParamIntensity(String key) {
|
||||
if (bodyBeautyGetMapping.containsKey(key)) {
|
||||
return bodyBeautyGetMapping.get(key).getValue();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置属性参数
|
||||
*
|
||||
* @param key 名称标识
|
||||
* @param value 结果值
|
||||
*/
|
||||
@Override
|
||||
public void updateParamIntensity(String key, double value) {
|
||||
if (bodyBeautySetMapping.containsKey(key)) {
|
||||
bodyBeautySetMapping.get(key).setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableBodyBeauty(boolean enable) {
|
||||
if (mFURenderKit.getBodyBeauty() != null) {
|
||||
mFURenderKit.getBodyBeauty().setEnable(enable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前模型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private BodyBeauty getCurrentBodyBeautyModel() {
|
||||
return bodyBeauty;
|
||||
}
|
||||
|
||||
|
||||
/*模型映射设置模型值*/
|
||||
private final HashMap<String, BodyBeautySetParamInterface> bodyBeautySetMapping = new HashMap<String, BodyBeautySetParamInterface>() {
|
||||
{
|
||||
put(BodyBeautyParam.BODY_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setBodySlimIntensity(value));
|
||||
put(BodyBeautyParam.LEG_STRETCH_INTENSITY, value -> getCurrentBodyBeautyModel().setLegStretchIntensity(value));
|
||||
put(BodyBeautyParam.WAIST_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setWaistSlimIntensity(value));
|
||||
put(BodyBeautyParam.SHOULDER_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setShoulderSlimIntensity(value));
|
||||
put(BodyBeautyParam.HIP_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setHipSlimIntensity(value));
|
||||
put(BodyBeautyParam.HEAD_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setHeadSlimIntensity(value));
|
||||
put(BodyBeautyParam.LEG_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setLegSlimIntensity(value));
|
||||
}
|
||||
};
|
||||
|
||||
/*模型映射获取模型值*/
|
||||
HashMap<String, BodyBeautyGetParamInterface> bodyBeautyGetMapping = new HashMap<String, BodyBeautyGetParamInterface>() {
|
||||
{
|
||||
put(BodyBeautyParam.BODY_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getBodySlimIntensity());
|
||||
put(BodyBeautyParam.LEG_STRETCH_INTENSITY, ()->getCurrentBodyBeautyModel().getLegStretchIntensity());
|
||||
put(BodyBeautyParam.WAIST_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getWaistSlimIntensity());
|
||||
put(BodyBeautyParam.SHOULDER_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getShoulderSlimIntensity());
|
||||
put(BodyBeautyParam.HIP_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getHipSlimIntensity());
|
||||
put(BodyBeautyParam.HEAD_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getHeadSlimIntensity());
|
||||
put(BodyBeautyParam.LEG_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getLegSlimIntensity());
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFUAIKit.loadAIProcessor(FaceUnityConfig.getAIHumanBundle(), FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
mFUAIKit.setMaxFaces(1);
|
||||
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
mFURenderKit.setBodyBeauty(bodyBeauty);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束需要释放AI驱动
|
||||
*/
|
||||
public void releaseAIProcessor() {
|
||||
mFUAIKit.releaseAIProcessor(FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import com.faceunity.core.model.facebeauty.FaceBeautyBlurTypeEnum;
|
||||
import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 保存到磁盘的对象
|
||||
* 该例只保存特效demo展示出来的美颜功能
|
||||
*/
|
||||
public class FaceBeautyData implements Serializable {
|
||||
/* 美肤 */
|
||||
/* 磨皮类型 */
|
||||
public int blurType = FaceBeautyBlurTypeEnum.FineSkin;
|
||||
/* 磨皮程度 */
|
||||
public double blurIntensity = 0.0;
|
||||
/* 美白程度 */
|
||||
public double colorIntensity = 0.0;
|
||||
/* 红润程度 */
|
||||
public double redIntensity = 0.0;
|
||||
/* 锐化程度 */
|
||||
public double sharpenIntensity = 0.0;
|
||||
/* 亮眼程度 */
|
||||
public double eyeBrightIntensity = 0.0;
|
||||
/* 美牙程度 */
|
||||
public double toothIntensity = 0.0;
|
||||
/* 去黑眼圈强度*/
|
||||
public double removePouchIntensity = 0.0;
|
||||
/* 去法令纹强度*/
|
||||
public double removeLawPatternIntensity = 0.0;
|
||||
|
||||
/*美型*/
|
||||
/* 瘦脸程度 */
|
||||
public double cheekThinningIntensity = 0.0;
|
||||
/* V脸程度 */
|
||||
public double cheekVIntensity = 0.0;
|
||||
/* 窄脸程度 */
|
||||
public double cheekNarrowIntensity = 0.0;
|
||||
/* 短脸程度 */
|
||||
public double cheekShortIntensity = 0.0;
|
||||
/* 小脸程度 */
|
||||
public double cheekSmallIntensity = 0.0;
|
||||
/* 瘦颧骨 */
|
||||
public double cheekBonesIntensity = 0.0;
|
||||
/* 瘦下颌骨 */
|
||||
public double lowerJawIntensity = 0.0;
|
||||
/* 大眼程度 */
|
||||
public double eyeEnlargingIntensity = 0.0;
|
||||
/* 圆眼程度 */
|
||||
public double eyeCircleIntensity = 0.0;
|
||||
/* 下巴调整程度 */
|
||||
public double chinIntensity = 0.5;
|
||||
/* 额头调整程度 */
|
||||
public double forHeadIntensity = 0.5;
|
||||
/* 瘦鼻程度 */
|
||||
public double noseIntensity = 0.0;
|
||||
/* 嘴巴调整程度 */
|
||||
public double mouthIntensity = 0.5;
|
||||
/* 开眼角强度 */
|
||||
public double canthusIntensity = 0.0;
|
||||
/* 眼睛间距 */
|
||||
public double eyeSpaceIntensity = 0.5;
|
||||
/* 眼睛角度 */
|
||||
public double eyeRotateIntensity = 0.5;
|
||||
/* 鼻子长度 */
|
||||
public double longNoseIntensity = 0.5;
|
||||
/* 调节人中 */
|
||||
public double philtrumIntensity = 0.5;
|
||||
/* 微笑嘴角强度 */
|
||||
public double smileIntensity = 0.0;
|
||||
/* 眉毛上下 */
|
||||
public double browHeightIntensity = 0.5;
|
||||
/* 眉毛间距 */
|
||||
public double browSpaceIntensity = 0.5;
|
||||
/* 眼睑 */
|
||||
public double eyeLidIntensity = 0.0;
|
||||
/* 眼睛高度 */
|
||||
public double eyeHeightIntensity = 0.5;
|
||||
/* 眉毛粗细 */
|
||||
public double browThickIntensity = 0.5;
|
||||
/* 嘴巴厚度 */
|
||||
public double lipThickIntensity = 0.5;
|
||||
/* 五官立体 */
|
||||
public double faceThreeIntensity = 0.5;
|
||||
|
||||
/* 风格推荐 */
|
||||
/* 是否开启风格推荐 */
|
||||
/* 风格推荐类型 */
|
||||
public int styleTypeIndex = -1;
|
||||
|
||||
//所有滤镜
|
||||
public HashMap<String,Double> filterMap = new HashMap<>();
|
||||
|
||||
/* 滤镜相关 */
|
||||
/* 滤镜名称 */
|
||||
public String filterName = FaceBeautyFilterEnum.ORIGIN;
|
||||
/* 滤镜程度 */
|
||||
public double filterIntensity = 0.0f;
|
||||
}
|
||||
@@ -0,0 +1,470 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.faceunity.core.controller.facebeauty.FaceBeautyParam;
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.facebeauty.FaceBeauty;
|
||||
import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum;
|
||||
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyBean;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyFilterBean;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyStyleBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.infe.AbstractFaceBeautyDataFactory;
|
||||
import com.yunbao.faceunity.repo.FaceBeautySource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* DESC:美颜业务工厂
|
||||
* Created on 2021/3/1
|
||||
*/
|
||||
public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
|
||||
public interface FaceBeautyListener {
|
||||
/**
|
||||
* 风格切换
|
||||
*
|
||||
* @param res
|
||||
*/
|
||||
void onFilterSelected(int res);
|
||||
|
||||
/**
|
||||
* 美颜开关
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
void onFaceBeautyEnable(boolean enable);
|
||||
}
|
||||
|
||||
interface FaceBeautySetParamInterface {
|
||||
/**
|
||||
* 设置属性值
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setValue(double value);
|
||||
}
|
||||
|
||||
interface FaceBeautyGetParamInterface {
|
||||
/**
|
||||
* 获取属性值
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
double getValue();
|
||||
}
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
|
||||
/*推荐风格标识*/
|
||||
private static int currentStyleIndex = -1;
|
||||
|
||||
/*美颜缓存数据模型 用于普通美颜*/
|
||||
public static final FaceBeauty defaultFaceBeauty = FaceBeautySource.getDefaultFaceBeauty();
|
||||
|
||||
/*当前生效美颜数据模型 普通 or 风格的*/
|
||||
public static FaceBeauty faceBeauty = defaultFaceBeauty;
|
||||
|
||||
|
||||
/*默认滤镜选中下标*/
|
||||
private int currentFilterIndex = 0;
|
||||
/*业务回调*/
|
||||
private final FaceBeautyListener mFaceBeautyListener;
|
||||
|
||||
|
||||
public FaceBeautyDataFactory(FaceBeautyListener listener) {
|
||||
mFaceBeautyListener = listener;
|
||||
}
|
||||
public FaceBeautyDataFactory(){
|
||||
mFaceBeautyListener=new FaceBeautyListener() {
|
||||
@Override
|
||||
public void onFilterSelected(int res) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFaceBeautyEnable(boolean enable) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取美肤参数列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyBean> getSkinBeauty() {
|
||||
return FaceBeautySource.buildSkinParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取美型参数列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyBean> getShapeBeauty() {
|
||||
return FaceBeautySource.buildShapeParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取美型参数列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyBean> getShapeBeautySubItem() {
|
||||
return FaceBeautySource.buildFaceShapeSubItemParams();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取美肤、美型扩展参数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public HashMap<String, ModelAttributeData> getModelAttributeRange() {
|
||||
return FaceBeautySource.buildModelAttributeRange();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取滤镜参数列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyFilterBean> getBeautyFilters() {
|
||||
ArrayList<FaceBeautyFilterBean> filterBeans = FaceBeautySource.buildFilters();
|
||||
for (int i = 0; i < filterBeans.size(); i++) {
|
||||
if (filterBeans.get(i).getKey().equals(defaultFaceBeauty.getFilterName())) {
|
||||
filterBeans.get(i).setIntensity(defaultFaceBeauty.getFilterIntensity());
|
||||
currentFilterIndex = i;
|
||||
}
|
||||
}
|
||||
return filterBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前滤镜下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentFilterIndex() {
|
||||
return currentFilterIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前滤镜下标
|
||||
*
|
||||
* @param currentFilterIndex
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentFilterIndex(int currentFilterIndex) {
|
||||
this.currentFilterIndex = currentFilterIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取推荐风格列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyStyleBean> getBeautyStyles() {
|
||||
return FaceBeautySource.buildStylesParams();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前风格推荐标识
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentStyleIndex() {
|
||||
return currentStyleIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置风格推荐标识
|
||||
*
|
||||
* @param styleIndex
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentStyleIndex(int styleIndex) {
|
||||
currentStyleIndex = styleIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置风格推荐标识 来自于硬盘
|
||||
*
|
||||
* @param styleIndex
|
||||
*/
|
||||
public static void setDiskCurrentStyleIndex(int styleIndex) {
|
||||
currentStyleIndex = styleIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 美颜开关设置
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
@Override
|
||||
public void enableFaceBeauty(boolean enable) {
|
||||
mFaceBeautyListener.onFaceBeautyEnable(enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型参数
|
||||
*
|
||||
* @param key 名称标识
|
||||
* @return 属性值
|
||||
*/
|
||||
@Override
|
||||
public double getParamIntensity(@NonNull String key) {
|
||||
if (faceBeautyGetMapping.containsKey(key)) {
|
||||
return faceBeautyGetMapping.get(key).getValue();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模型参数
|
||||
*
|
||||
* @param key 名称标识
|
||||
* @param value 属性值
|
||||
*/
|
||||
@Override
|
||||
public void updateParamIntensity(@NonNull String key, double value) {
|
||||
if (faceBeautySetMapping.containsKey(key)) {
|
||||
faceBeautySetMapping.get(key).setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将所有效果制空
|
||||
*/
|
||||
@Override
|
||||
public void resetParamIntensity() {
|
||||
if (faceBeauty != defaultFaceBeauty) {
|
||||
faceBeauty = defaultFaceBeauty;
|
||||
FURenderKit.getInstance().setFaceBeauty(faceBeauty);
|
||||
}
|
||||
|
||||
ArrayList<FaceBeautyBean> skinBeauty = getSkinBeauty();
|
||||
ArrayList<FaceBeautyBean> shapeBeauty = getShapeBeauty();
|
||||
HashMap<String, ModelAttributeData> modelAttributeRange = getModelAttributeRange();
|
||||
|
||||
//还原美肤
|
||||
for (FaceBeautyBean faceBeautyBean : skinBeauty) {
|
||||
String key = faceBeautyBean.getKey();
|
||||
ModelAttributeData modelAttributeData = modelAttributeRange.get(key);
|
||||
updateParamIntensity(key, modelAttributeData.getStand());
|
||||
}
|
||||
|
||||
//还原美型
|
||||
for (FaceBeautyBean faceBeautyBean : shapeBeauty) {
|
||||
String key = faceBeautyBean.getKey();
|
||||
ModelAttributeData modelAttributeData = modelAttributeRange.get(key);
|
||||
updateParamIntensity(key, modelAttributeData.getStand());
|
||||
}
|
||||
|
||||
//还原滤镜
|
||||
defaultFaceBeauty.setFilterName(FaceBeautyFilterEnum.ORIGIN);
|
||||
defaultFaceBeauty.setFilterIntensity(0.0);
|
||||
setCurrentFilterIndex(0);
|
||||
|
||||
//设置风格角标
|
||||
setCurrentStyleIndex(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentOneHotFaceShape() {
|
||||
return CurrentFaceShapeUIValue.currentFaceShape == null ? FaceBeautyParam.CHEEK_V_INTENSITY : CurrentFaceShapeUIValue.currentFaceShape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentOneHotFaceShape(String faceShape) {
|
||||
CurrentFaceShapeUIValue.currentFaceShape = faceShape;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置当前脸型的UI值
|
||||
*/
|
||||
public void setCurrentFaceShapeUIValue(HashMap<String, Double> hashMap) {
|
||||
CurrentFaceShapeUIValue.currentFaceShapeValue.clear();
|
||||
CurrentFaceShapeUIValue.currentFaceShapeValue.putAll(hashMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前脸型的UI值
|
||||
*/
|
||||
public HashMap<String, Double> getCurrentFaceShapeUIValue() {
|
||||
return CurrentFaceShapeUIValue.currentFaceShapeValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换滤镜
|
||||
*
|
||||
* @param name 滤镜名称标识
|
||||
* @param intensity 滤镜强度
|
||||
* @param resID 滤镜名称
|
||||
*/
|
||||
@Override
|
||||
public void onFilterSelected(@NonNull String name, double intensity, int resID) {
|
||||
defaultFaceBeauty.setFilterName(name);
|
||||
defaultFaceBeauty.setFilterIntensity(intensity);
|
||||
mFaceBeautyListener.onFilterSelected(resID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更换滤镜强度
|
||||
*
|
||||
* @param intensity 滤镜强度
|
||||
*/
|
||||
@Override
|
||||
public void updateFilterIntensity(double intensity) {
|
||||
defaultFaceBeauty.setFilterIntensity(intensity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置推荐风格
|
||||
*
|
||||
* @param name 风格key
|
||||
*/
|
||||
@Override
|
||||
public void onStyleSelected(String name) {
|
||||
if (name == null) {
|
||||
faceBeauty = defaultFaceBeauty;
|
||||
FURenderKit.getInstance().setFaceBeauty(faceBeauty);
|
||||
} else {
|
||||
Runnable runnable = FaceBeautySource.styleParams.get(name);
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*模型映射设置模型值*/
|
||||
private final HashMap<String, FaceBeautySetParamInterface> faceBeautySetMapping = new HashMap<String, FaceBeautySetParamInterface>() {{
|
||||
put(FaceBeautyParam.COLOR_INTENSITY, defaultFaceBeauty::setColorIntensity);
|
||||
put(FaceBeautyParam.BLUR_INTENSITY, defaultFaceBeauty::setBlurIntensity);
|
||||
put(FaceBeautyParam.RED_INTENSITY, defaultFaceBeauty::setRedIntensity);
|
||||
put(FaceBeautyParam.SHARPEN_INTENSITY, defaultFaceBeauty::setSharpenIntensity);
|
||||
put(FaceBeautyParam.EYE_BRIGHT_INTENSITY, defaultFaceBeauty::setEyeBrightIntensity);
|
||||
put(FaceBeautyParam.TOOTH_WHITEN_INTENSITY, defaultFaceBeauty::setToothIntensity);
|
||||
put(FaceBeautyParam.REMOVE_POUCH_INTENSITY, defaultFaceBeauty::setRemovePouchIntensity);
|
||||
put(FaceBeautyParam.REMOVE_NASOLABIAL_FOLDS_INTENSITY, defaultFaceBeauty::setRemoveLawPatternIntensity);
|
||||
/*美型*/
|
||||
put(FaceBeautyParam.FACE_SHAPE_INTENSITY, defaultFaceBeauty::setSharpenIntensity);
|
||||
put(FaceBeautyParam.CHEEK_THINNING_INTENSITY, defaultFaceBeauty::setCheekThinningIntensity);
|
||||
put(FaceBeautyParam.CHEEK_V_INTENSITY, defaultFaceBeauty::setCheekVIntensity);
|
||||
put(FaceBeautyParam.CHEEK_LONG_INTENSITY, defaultFaceBeauty::setCheekLongIntensity);
|
||||
put(FaceBeautyParam.CHEEK_CIRCLE_INTENSITY, defaultFaceBeauty::setCheekCircleIntensity);
|
||||
put(FaceBeautyParam.CHEEK_NARROW_INTENSITY, defaultFaceBeauty::setCheekNarrowIntensity);
|
||||
put(FaceBeautyParam.CHEEK_SHORT_INTENSITY, defaultFaceBeauty::setCheekShortIntensity);
|
||||
put(FaceBeautyParam.CHEEK_SMALL_INTENSITY, defaultFaceBeauty::setCheekSmallIntensity);
|
||||
put(FaceBeautyParam.INTENSITY_CHEEKBONES_INTENSITY, defaultFaceBeauty::setCheekBonesIntensity);
|
||||
put(FaceBeautyParam.INTENSITY_LOW_JAW_INTENSITY, defaultFaceBeauty::setLowerJawIntensity);
|
||||
put(FaceBeautyParam.EYE_ENLARGING_INTENSITY, defaultFaceBeauty::setEyeEnlargingIntensity);
|
||||
put(FaceBeautyParam.EYE_CIRCLE_INTENSITY, defaultFaceBeauty::setEyeCircleIntensity);
|
||||
put(FaceBeautyParam.BROW_HEIGHT_INTENSITY, defaultFaceBeauty::setBrowHeightIntensity);
|
||||
put(FaceBeautyParam.BROW_SPACE_INTENSITY, defaultFaceBeauty::setBrowSpaceIntensity);
|
||||
put(FaceBeautyParam.CHIN_INTENSITY, defaultFaceBeauty::setChinIntensity);
|
||||
put(FaceBeautyParam.FOREHEAD_INTENSITY, defaultFaceBeauty::setForHeadIntensity);
|
||||
put(FaceBeautyParam.NOSE_INTENSITY, defaultFaceBeauty::setNoseIntensity);
|
||||
put(FaceBeautyParam.MOUTH_INTENSITY, defaultFaceBeauty::setMouthIntensity);
|
||||
put(FaceBeautyParam.CANTHUS_INTENSITY, defaultFaceBeauty::setCanthusIntensity);
|
||||
put(FaceBeautyParam.EYE_SPACE_INTENSITY, defaultFaceBeauty::setEyeSpaceIntensity);
|
||||
put(FaceBeautyParam.EYE_ROTATE_INTENSITY, defaultFaceBeauty::setEyeRotateIntensity);
|
||||
put(FaceBeautyParam.LONG_NOSE_INTENSITY, defaultFaceBeauty::setLongNoseIntensity);
|
||||
put(FaceBeautyParam.PHILTRUM_INTENSITY, defaultFaceBeauty::setPhiltrumIntensity);
|
||||
put(FaceBeautyParam.SMILE_INTENSITY, defaultFaceBeauty::setSmileIntensity);
|
||||
}};
|
||||
|
||||
/*模型映射获取模型值*/
|
||||
HashMap<String, FaceBeautyGetParamInterface> faceBeautyGetMapping = new HashMap<String, FaceBeautyGetParamInterface>() {
|
||||
{
|
||||
put(FaceBeautyParam.COLOR_INTENSITY, defaultFaceBeauty::getColorIntensity);
|
||||
put(FaceBeautyParam.BLUR_INTENSITY, defaultFaceBeauty::getBlurIntensity);
|
||||
put(FaceBeautyParam.RED_INTENSITY, defaultFaceBeauty::getRedIntensity);
|
||||
put(FaceBeautyParam.SHARPEN_INTENSITY, defaultFaceBeauty::getSharpenIntensity);
|
||||
put(FaceBeautyParam.EYE_BRIGHT_INTENSITY, defaultFaceBeauty::getEyeBrightIntensity);
|
||||
put(FaceBeautyParam.TOOTH_WHITEN_INTENSITY, defaultFaceBeauty::getToothIntensity);
|
||||
put(FaceBeautyParam.REMOVE_POUCH_INTENSITY, defaultFaceBeauty::getRemovePouchIntensity);
|
||||
put(FaceBeautyParam.REMOVE_NASOLABIAL_FOLDS_INTENSITY, defaultFaceBeauty::getRemoveLawPatternIntensity);
|
||||
/*美型*/
|
||||
put(FaceBeautyParam.FACE_SHAPE_INTENSITY, defaultFaceBeauty::getSharpenIntensity);
|
||||
put(FaceBeautyParam.CHEEK_THINNING_INTENSITY, defaultFaceBeauty::getCheekThinningIntensity);
|
||||
put(FaceBeautyParam.CHEEK_V_INTENSITY, defaultFaceBeauty::getCheekVIntensity);
|
||||
put(FaceBeautyParam.CHEEK_LONG_INTENSITY, defaultFaceBeauty::getCheekLongIntensity);
|
||||
put(FaceBeautyParam.CHEEK_CIRCLE_INTENSITY, defaultFaceBeauty::getCheekCircleIntensity);
|
||||
put(FaceBeautyParam.CHEEK_NARROW_INTENSITY, defaultFaceBeauty::getCheekNarrowIntensity);
|
||||
put(FaceBeautyParam.CHEEK_SHORT_INTENSITY, defaultFaceBeauty::getCheekShortIntensity);
|
||||
put(FaceBeautyParam.CHEEK_SMALL_INTENSITY, defaultFaceBeauty::getCheekSmallIntensity);
|
||||
put(FaceBeautyParam.INTENSITY_CHEEKBONES_INTENSITY, defaultFaceBeauty::getCheekBonesIntensity);
|
||||
put(FaceBeautyParam.INTENSITY_LOW_JAW_INTENSITY, defaultFaceBeauty::getLowerJawIntensity);
|
||||
put(FaceBeautyParam.EYE_ENLARGING_INTENSITY, defaultFaceBeauty::getEyeEnlargingIntensity);
|
||||
put(FaceBeautyParam.EYE_CIRCLE_INTENSITY, defaultFaceBeauty::getEyeCircleIntensity);
|
||||
put(FaceBeautyParam.BROW_HEIGHT_INTENSITY, defaultFaceBeauty::getBrowHeightIntensity);
|
||||
put(FaceBeautyParam.BROW_SPACE_INTENSITY, defaultFaceBeauty::getBrowSpaceIntensity);
|
||||
put(FaceBeautyParam.CHIN_INTENSITY, defaultFaceBeauty::getChinIntensity);
|
||||
put(FaceBeautyParam.FOREHEAD_INTENSITY, defaultFaceBeauty::getForHeadIntensity);
|
||||
put(FaceBeautyParam.NOSE_INTENSITY, defaultFaceBeauty::getNoseIntensity);
|
||||
put(FaceBeautyParam.MOUTH_INTENSITY, defaultFaceBeauty::getMouthIntensity);
|
||||
put(FaceBeautyParam.CANTHUS_INTENSITY, defaultFaceBeauty::getCanthusIntensity);
|
||||
put(FaceBeautyParam.EYE_SPACE_INTENSITY, defaultFaceBeauty::getEyeSpaceIntensity);
|
||||
put(FaceBeautyParam.EYE_ROTATE_INTENSITY, defaultFaceBeauty::getEyeRotateIntensity);
|
||||
put(FaceBeautyParam.LONG_NOSE_INTENSITY, defaultFaceBeauty::getLongNoseIntensity);
|
||||
put(FaceBeautyParam.PHILTRUM_INTENSITY, defaultFaceBeauty::getPhiltrumIntensity);
|
||||
put(FaceBeautyParam.SMILE_INTENSITY, defaultFaceBeauty::getSmileIntensity);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFURenderKit.setFaceBeauty(faceBeauty);
|
||||
FUAIKit.getInstance().setMaxFaces(4);
|
||||
if (FaceUnityConfig.IS_OPEN_LAND_MARK) {
|
||||
ExpressionRecognition expressionRecognition = new ExpressionRecognition(new FUBundleData(FaceUnityConfig.BUNDLE_LANDMARKS));
|
||||
expressionRecognition.setLandmarksType(FUAITypeEnum.FUAITYPE_FACELANDMARKS239);
|
||||
mFURenderKit.getPropContainer().addProp(expressionRecognition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于记录当前脸型的UI值 -> 用于用户下次点入的时候恢复
|
||||
*/
|
||||
static class CurrentFaceShapeUIValue {
|
||||
/* 当前生效的脸型 */
|
||||
public static String currentFaceShape = FaceBeautyParam.CHEEK_V_INTENSITY;
|
||||
/* 当前脸型的UI值 */
|
||||
public static HashMap<String, Double> currentFaceShapeValue = new HashMap<>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
public class FaceParam {
|
||||
public static final int FACE_BEAUTY=100;//美颜
|
||||
public static final int FACE_BEAUTY_SKIN=101;//美肤
|
||||
public static final int FACE_BEAUTY_SHAPE=102;//美型
|
||||
public static final int FACE_BEAUTY_FILTER=103;//滤镜
|
||||
public static final int FACE_BEAUTY_STYLE=104;//风格推荐
|
||||
public static final int FACE_MAKEUP=200;//美妆
|
||||
public static final int FACE_MAKEUP_TYPE_FOUNDATION=201;//粉底
|
||||
public static final int FACE_MAKEUP_TYPE_LIP_STICK=202;//口红
|
||||
public static final int FACE_MAKEUP_TYPE_BLUSHER=203;//腮红
|
||||
public static final int FACE_MAKEUP_TYPE_EYE_BROW=204;//眉毛
|
||||
public static final int FACE_MAKEUP_TYPE_EYE_SHADOW=205;//眼影
|
||||
public static final int FACE_MAKEUP_TYPE_EYE_LINER=206;//眼线
|
||||
public static final int FACE_MAKEUP_TYPE_EYE_LASH=207;//睫毛
|
||||
public static final int FACE_MAKEUP_TYPE_HIGH_LIGHT=208;//高光
|
||||
public static final int FACE_MAKEUP_TYPE_SHADOW=209;//阴影
|
||||
public static final int FACE_MAKEUP_TYPE_EYE_PUPIL=210;//美瞳
|
||||
public static final int FACE_BEAUTY_BODY=300;//美体
|
||||
public static final int FACE_BIG_HEAD=400;//大头
|
||||
public static final int FACE_ANIMOJI=500;//Animoji
|
||||
public static final int FACE_STICKER=600;//贴纸
|
||||
public static final int FACE_FINE_STICKER=700;//精品贴纸
|
||||
public static final int FACE_FINE_STICKER_MIDDLE=701;//中级道具
|
||||
public static final int FACE_FINE_STICKER_HIGH=702;//高级道具
|
||||
public static final int FACE_FINE_STICKER_GAME=703;//游戏道具
|
||||
public static final int FACE_ANIM=800;//动漫滤镜
|
||||
// 占位符,以下均未使用
|
||||
public static final int FACE_ANIM_AR_MASK=900;
|
||||
public static final int FACE_EXPRESSION_RECOGNITION=1000;
|
||||
public static final int FACE_FACE_WARP=1100;
|
||||
public static final int FACE_GESTURE_RECOGNITION=1200;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import com.faceunity.core.enumeration.FUAIProcessorEnum;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.yunbao.faceunity.entity.PropBean;
|
||||
import com.yunbao.faceunity.utils.FURenderer;
|
||||
|
||||
/**
|
||||
* DESC:
|
||||
* Created on 2021/4/25
|
||||
*/
|
||||
public class FaceUnityDataFactory {
|
||||
|
||||
/**
|
||||
* 道具数据工厂
|
||||
*/
|
||||
public FaceBeautyDataFactory mFaceBeautyDataFactory;
|
||||
public BodyBeautyDataFactory mBodyBeautyDataFactory;
|
||||
public MakeupDataFactory mMakeupDataFactory;
|
||||
public PropDataFactory mPropDataFactory;
|
||||
|
||||
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
private FURenderer mFURenderer = FURenderer.getInstance();
|
||||
|
||||
private static FaceUnityDataFactory sInstance;
|
||||
public static FaceUnityDataFactory getInstance() {
|
||||
if (sInstance == null) {
|
||||
synchronized (FaceUnityDataFactory.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new FaceUnityDataFactory(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public static void release() {
|
||||
sInstance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 道具加载标识
|
||||
*/
|
||||
public int currentFunctionIndex;
|
||||
private boolean hasFaceBeautyLoaded = false;
|
||||
private boolean hasBodyBeautyLoaded = false;
|
||||
private boolean hasMakeupLoaded = false;
|
||||
private boolean hasPropLoaded = false;
|
||||
|
||||
|
||||
public FaceUnityDataFactory(int index) {
|
||||
currentFunctionIndex = index;
|
||||
mFaceBeautyDataFactory = new FaceBeautyDataFactory(new FaceBeautyDataFactory.FaceBeautyListener() {
|
||||
@Override
|
||||
public void onFilterSelected(int res) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFaceBeautyEnable(boolean enable) {
|
||||
|
||||
}
|
||||
});
|
||||
mBodyBeautyDataFactory = new BodyBeautyDataFactory();
|
||||
mMakeupDataFactory = new MakeupDataFactory(0);
|
||||
mPropDataFactory = new PropDataFactory(new PropDataFactory.PropListener() {
|
||||
@Override
|
||||
public void onItemSelected(PropBean bean) {
|
||||
|
||||
}
|
||||
},0,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
switch (currentFunctionIndex) {
|
||||
case 0:
|
||||
mFaceBeautyDataFactory.bindCurrentRenderer();
|
||||
hasFaceBeautyLoaded = true;
|
||||
break;
|
||||
case 1:
|
||||
mPropDataFactory.bindCurrentRenderer();
|
||||
hasPropLoaded = true;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
mMakeupDataFactory.bindCurrentRenderer();
|
||||
hasMakeupLoaded = true;
|
||||
break;
|
||||
case 3:
|
||||
mBodyBeautyDataFactory.bindCurrentRenderer();
|
||||
hasBodyBeautyLoaded = true;
|
||||
break;
|
||||
}
|
||||
if (hasFaceBeautyLoaded && currentFunctionIndex != 0) {
|
||||
mFaceBeautyDataFactory.bindCurrentRenderer();
|
||||
}
|
||||
if (hasPropLoaded && currentFunctionIndex != 1) {
|
||||
mPropDataFactory.bindCurrentRenderer();
|
||||
}
|
||||
if (hasMakeupLoaded && currentFunctionIndex != 2) {
|
||||
mMakeupDataFactory.bindCurrentRenderer();
|
||||
}
|
||||
if (hasBodyBeautyLoaded && currentFunctionIndex != 3) {
|
||||
mBodyBeautyDataFactory.bindCurrentRenderer();
|
||||
}
|
||||
if (currentFunctionIndex == 3) {
|
||||
mFURenderKit.getFUAIController().setMaxFaces(1);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.HUMAN_PROCESSOR);
|
||||
} else {
|
||||
mFURenderKit.getFUAIController().setMaxFaces(4);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.FACE_PROCESSOR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 道具功能切换
|
||||
*/
|
||||
public void onFunctionSelected(int index) {
|
||||
currentFunctionIndex = index;
|
||||
switch (index) {
|
||||
case 0:
|
||||
if (!hasFaceBeautyLoaded) {
|
||||
mFaceBeautyDataFactory.bindCurrentRenderer();
|
||||
hasFaceBeautyLoaded = true;
|
||||
}
|
||||
mFURenderKit.getFUAIController().setMaxFaces(4);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.FACE_PROCESSOR);
|
||||
break;
|
||||
case 1:
|
||||
if (!hasPropLoaded) {
|
||||
mPropDataFactory.bindCurrentRenderer();
|
||||
hasPropLoaded = true;
|
||||
}
|
||||
mFURenderKit.getFUAIController().setMaxFaces(4);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.FACE_PROCESSOR);
|
||||
break;
|
||||
case 2:
|
||||
if (!hasMakeupLoaded) {
|
||||
mMakeupDataFactory.bindCurrentRenderer();
|
||||
hasMakeupLoaded = true;
|
||||
}
|
||||
mFURenderKit.getFUAIController().setMaxFaces(4);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.FACE_PROCESSOR);
|
||||
break;
|
||||
case 3:
|
||||
if (!hasBodyBeautyLoaded) {
|
||||
mBodyBeautyDataFactory.bindCurrentRenderer();
|
||||
hasBodyBeautyLoaded = true;
|
||||
}
|
||||
mFURenderKit.getFUAIController().setMaxFaces(1);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.HUMAN_PROCESSOR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,405 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
|
||||
import com.faceunity.core.avatar.model.Avatar;
|
||||
import com.faceunity.core.avatar.model.Scene;
|
||||
import com.faceunity.core.avatar.scene.ProcessorConfig;
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.entity.FUTranslationScale;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.faceunity.FUSceneKit;
|
||||
import com.faceunity.core.model.antialiasing.Antialiasing;
|
||||
import com.faceunity.core.model.prop.sticker.FineSticker;
|
||||
import com.faceunity.core.utils.FileUtils;
|
||||
|
||||
import com.yunbao.faceunity.entity.net.FineStickerEntity;
|
||||
import com.yunbao.faceunity.entity.net.FineStickerTagEntity;
|
||||
import com.yunbao.faceunity.infe.AbstractFineStickerDataFactory;
|
||||
import com.yunbao.faceunity.repo.AvatarSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
import com.yunbao.faceunity.utils.net.StickerDownloadHelper;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created on 2021/3/31 0031 15:28.
|
||||
* Author: xloger
|
||||
* Email:phoenix@xloger.com
|
||||
*/
|
||||
public class FineStickerDataFactory extends AbstractFineStickerDataFactory {
|
||||
private static final String TAG = "FineStickerDataFactory";
|
||||
private static FineStickerDataFactory factory;
|
||||
public static FineStickerDataFactory getInstance(){
|
||||
if(factory==null){
|
||||
factory=new FineStickerDataFactory();
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*渲染控制器*/
|
||||
private final FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
private FUAIKit mFUAIKit = FUAIKit.getInstance();
|
||||
/*当前选中道具模型*/
|
||||
private FineSticker currentProp;
|
||||
/*菜单视图*/
|
||||
/*当前选中道具*/
|
||||
private FineStickerEntity.DocsBean currentSticker;
|
||||
/*当前道具的类型 普通单bundle,avatar 默认为普通单bundle*/
|
||||
private BundleType mCurrentBundleType = BundleType.NORMAL_SINGLE_BUNDLE;
|
||||
|
||||
//avatar相关
|
||||
/* 场景 */
|
||||
private Scene mSceneModel;
|
||||
/* 对象 */
|
||||
private Avatar mCurrentAvatarModel;
|
||||
/*3D抗锯齿*/
|
||||
public Antialiasing antialiasing;
|
||||
|
||||
//回调
|
||||
private List<StickerDownloadHelper.Callback> callbacks;
|
||||
|
||||
//avatar用于区分bundle类型的关键字
|
||||
private final String COMPONENTS_STR = "components";
|
||||
private final String ANIM_STR = "anim";
|
||||
private final String INFO = "info.json";
|
||||
private final String ZIP = ".zip";
|
||||
private final String AVATAR = "avatar";
|
||||
|
||||
private FineStickerDataFactory() {
|
||||
callbacks=new ArrayList<>();
|
||||
StickerDownloadHelper.getInstance().setCallback(downloadHelper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定菜单视图
|
||||
*
|
||||
*/
|
||||
public void bindView() {
|
||||
|
||||
}
|
||||
|
||||
public void addCallback(StickerDownloadHelper.Callback downloadHelper) {
|
||||
callbacks.add(downloadHelper);
|
||||
}
|
||||
public void removeCallback(StickerDownloadHelper.Callback downloadHelper){
|
||||
callbacks.remove(downloadHelper);
|
||||
}
|
||||
private void removeAllCallback(){
|
||||
callbacks.clear();
|
||||
}
|
||||
|
||||
public void refuseEvent() {
|
||||
StickerDownloadHelper.getInstance().setCallback(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换道具
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void onItemSelected(FineStickerEntity.DocsBean bean) {
|
||||
currentSticker = bean;
|
||||
if (bean != null && bean.getTool().getBundle().getUid().endsWith(ZIP)) {
|
||||
//复合道具
|
||||
if (AVATAR.equals(bean.getTool().getCategory())) {
|
||||
//avatar道具
|
||||
if (mCurrentBundleType == BundleType.NORMAL_SINGLE_BUNDLE) {
|
||||
//移除旧的道具
|
||||
mFURenderKit.getPropContainer().removeAllProp();
|
||||
currentProp = null;
|
||||
adapterMaxFace();
|
||||
}
|
||||
if (bean.getUnZipFilePaths() != null) {
|
||||
buildAvatarModel(bean);
|
||||
//当前为 avatar bundle
|
||||
mCurrentBundleType = BundleType.AVATAR_BUNDLE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//普通道具
|
||||
if (mCurrentBundleType == BundleType.NORMAL_SINGLE_BUNDLE) {
|
||||
mFURenderKit.getPropContainer().removeAllProp();
|
||||
currentProp = null;
|
||||
if (bean != null && bean.getFilePath() != null && bean.getFilePath().trim().length() > 0) {
|
||||
adapterMaxFace();
|
||||
FineSticker prop = adapterBean(bean.getFilePath());
|
||||
mFURenderKit.getPropContainer().addProp(prop);
|
||||
currentProp = prop;
|
||||
}
|
||||
} else if (mCurrentBundleType == BundleType.AVATAR_BUNDLE) {
|
||||
//关闭avatar 相关的东西
|
||||
if (mSceneModel != null && mCurrentAvatarModel != null) {
|
||||
mSceneModel.removeAvatar(mCurrentAvatarModel);
|
||||
FUSceneKit.getInstance().removeScene(mSceneModel);
|
||||
mSceneModel = null;
|
||||
mCurrentAvatarModel = null;
|
||||
}
|
||||
|
||||
//设置道具
|
||||
if (bean != null && bean.getFilePath() != null && bean.getFilePath().trim().length() > 0) {
|
||||
adapterMaxFace();
|
||||
FineSticker prop = adapterBean(bean.getFilePath());
|
||||
mFURenderKit.getPropContainer().addProp(prop);
|
||||
currentProp = prop;
|
||||
}
|
||||
}
|
||||
|
||||
//当前为普通bundle
|
||||
mCurrentBundleType = BundleType.NORMAL_SINGLE_BUNDLE;
|
||||
}
|
||||
|
||||
if (mBundleTypeListener != null) {
|
||||
mBundleTypeListener.bundleType(mCurrentBundleType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建avatar -> scene
|
||||
* @param bean
|
||||
*/
|
||||
private void buildAvatarModel(FineStickerEntity.DocsBean bean) {
|
||||
//启动avatar基本逻辑
|
||||
if (antialiasing == null)
|
||||
antialiasing = new Antialiasing(new FUBundleData(FaceUnityConfig.BUNDLE_ANTI_ALIASING));
|
||||
//3d抗锯齿
|
||||
mFURenderKit.setAntialiasing(antialiasing);
|
||||
//判断是avatar 控件 -> 查看是否有json文件
|
||||
ArrayList<String> unZipFilePaths = bean.getUnZipFilePaths();
|
||||
int hasJson = unZipFilePaths.indexOf(INFO);
|
||||
|
||||
ArrayList<String> strComponents = new ArrayList<>();//组件Bundle
|
||||
ArrayList<String> strAnimations = new ArrayList<>();//动画Bundle
|
||||
if (hasJson >= 0) {
|
||||
//用json的描述赋予每一个bundle自己的职责,还可以赋予其他参数
|
||||
String jsonPath = bean.getFilePath().substring(0,bean.getFilePath().lastIndexOf(".")) + "/" + unZipFilePaths.get(hasJson);
|
||||
//解析json文件 ->
|
||||
String json = FileUtils.loadStringFromExternal(jsonPath);
|
||||
//解析avatar的json文件
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(json);
|
||||
JSONArray components = jsonObject.getJSONArray("components");
|
||||
for(int i =0 ;i < components.length();i++) {
|
||||
String path = bean.getFilePath().substring(0,bean.getFilePath().lastIndexOf(".")) + "/" + components.get(i);
|
||||
strComponents.add(path);
|
||||
}
|
||||
|
||||
JSONArray anims = jsonObject.getJSONArray("anims");
|
||||
for(int i =0 ;i < anims.length();i++) {
|
||||
String path = bean.getFilePath().substring(0,bean.getFilePath().lastIndexOf(".")) + "/" + anims.get(i);
|
||||
strAnimations.add(path);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
//根据bundle的命名赋予每一个bundle自己的职责
|
||||
for (String str:unZipFilePaths) {
|
||||
if (str.startsWith(COMPONENTS_STR)) {
|
||||
String path = bean.getFilePath().substring(0,bean.getFilePath().lastIndexOf(".")) + "/" + str;
|
||||
strComponents.add(path);
|
||||
} else if (str.startsWith(ANIM_STR)){
|
||||
String path = bean.getFilePath().substring(0,bean.getFilePath().lastIndexOf(".")) + "/" + str;
|
||||
strAnimations.add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mSceneModel == null) {
|
||||
mCurrentAvatarModel = AvatarSource.buildAvatarData(strComponents,strAnimations);
|
||||
mSceneModel = AvatarSource.buildSceneModel(mCurrentAvatarModel);
|
||||
mSceneModel.processorConfig.setTrackScene(ProcessorConfig.TrackScene.SceneFull);
|
||||
mCurrentAvatarModel.transForm.setTranslationScale(new FUTranslationScale(0.5f, 0f, 0.1f));
|
||||
} else {
|
||||
if (mCurrentAvatarModel != null)
|
||||
mSceneModel.removeAvatar(mCurrentAvatarModel);
|
||||
mCurrentAvatarModel = AvatarSource.buildAvatarData(strComponents,strAnimations);
|
||||
mSceneModel.addAvatar(mCurrentAvatarModel);
|
||||
}
|
||||
FUSceneKit.getInstance().addScene(mSceneModel);
|
||||
FUSceneKit.getInstance().setCurrentScene(mSceneModel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据adpater 调整业务模型
|
||||
* 0:维持竖屏
|
||||
* 1:仅限一人
|
||||
* 2:美妆道具
|
||||
* 3:点击事件
|
||||
* 4:翻转
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private FineSticker adapterBean(String path) {
|
||||
String adapter = currentSticker.getTool().getAdapter();
|
||||
if (adapter == null || !adapter.contains("1")) {
|
||||
mFUAIKit.setMaxFaces(4);
|
||||
} else {
|
||||
mFUAIKit.setMaxFaces(1);
|
||||
}
|
||||
if (adapter != null && adapter.trim().length() > 0) {
|
||||
boolean isFlipPoints = adapter.contains("2");
|
||||
boolean is3DFlipH = adapter.contains("4");
|
||||
boolean isClick = adapter.contains("3");
|
||||
return new FineSticker(new FUBundleData(path), isFlipPoints, is3DFlipH, isClick);
|
||||
} else {
|
||||
return new FineSticker(new FUBundleData(path));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 网络回调
|
||||
*/
|
||||
private StickerDownloadHelper.Callback downloadHelper = new StickerDownloadHelper.Callback() {
|
||||
@Override
|
||||
public void onGetTags(String[] tags) {
|
||||
for (StickerDownloadHelper.Callback callback : callbacks) {
|
||||
callback.onGetTags(tags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetList(String tag, FineStickerEntity fineSticker) {
|
||||
for (StickerDownloadHelper.Callback callback : callbacks) {
|
||||
callback.onGetList(tag, fineSticker);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownload(FineStickerEntity.DocsBean entity) {
|
||||
for (StickerDownloadHelper.Callback callback : callbacks) {
|
||||
callback.onDownload(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadError(FineStickerEntity.DocsBean entity, String msg) {
|
||||
for (StickerDownloadHelper.Callback callback : callbacks) {
|
||||
callback.onDownloadError(entity, msg);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 获取标签列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public List<FineStickerTagEntity> loadTagList() {
|
||||
String[] tags = StickerDownloadHelper.getInstance().tags();
|
||||
return formatTag(tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取标签对应道具列表
|
||||
*
|
||||
* @param tag
|
||||
* @return
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public FineStickerEntity loadStickerList(@NotNull FineStickerTagEntity tag) {
|
||||
return StickerDownloadHelper.getInstance().tools(tag.getTag());
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载道具
|
||||
*
|
||||
* @param docsBean
|
||||
*/
|
||||
@Override
|
||||
public void downloadSticker(@NotNull FineStickerEntity.DocsBean docsBean) {
|
||||
try{
|
||||
StickerDownloadHelper.getInstance().download(docsBean);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG,"downloadSticker",e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数据转换
|
||||
*
|
||||
* @param tags
|
||||
* @return
|
||||
*/
|
||||
public static List<FineStickerTagEntity> formatTag(String[] tags) {
|
||||
List<FineStickerTagEntity> tagEntityList = new ArrayList<>(tags.length);
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
tagEntityList.add(new FineStickerTagEntity(tags[i]));
|
||||
}
|
||||
return tagEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFUAIKit.loadAIProcessor(FaceUnityConfig.getAIHumanBundle(), FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
mFUAIKit.loadAIProcessor(FaceUnityConfig.BUNDLE_AI_HAND, FUAITypeEnum.FUAITYPE_HANDGESTURE);
|
||||
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
mFUAIKit.setMaxFaces(1);
|
||||
onItemSelected(currentSticker);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 结束需要释放AI驱动
|
||||
*/
|
||||
public void releaseAIProcessor() {
|
||||
mFUAIKit.releaseAIProcessor(FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
mFUAIKit.releaseAIProcessor(FUAITypeEnum.FUAITYPE_HANDGESTURE);
|
||||
}
|
||||
|
||||
|
||||
private void adapterMaxFace() {
|
||||
if (currentSticker == null) return;
|
||||
String adapter = currentSticker.getTool().getAdapter();
|
||||
if (adapter == null || !adapter.contains("1")) {
|
||||
mFUAIKit.setMaxFaces(4);
|
||||
} else {
|
||||
mFUAIKit.setMaxFaces(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void onTouchEvent(MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP && currentProp != null && currentProp.isClick()) {
|
||||
currentProp.onClick();
|
||||
}
|
||||
}
|
||||
|
||||
//通过枚举记录每一个bundle的类型
|
||||
public enum BundleType {
|
||||
NORMAL_SINGLE_BUNDLE,//普通的单bundle道具
|
||||
AVATAR_BUNDLE//avatar bundle 一般为多bundle
|
||||
}
|
||||
|
||||
private BundleTypeListener mBundleTypeListener;
|
||||
public interface BundleTypeListener {
|
||||
void bundleType(BundleType bundleType);
|
||||
}
|
||||
public void setBundleTypeListener (BundleTypeListener bundleTypeListener){
|
||||
mBundleTypeListener = bundleTypeListener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
|
||||
import com.yunbao.faceunity.entity.LightMakeupBean;
|
||||
import com.yunbao.faceunity.infe.AbstractLightMakeupDataFactory;
|
||||
import com.yunbao.faceunity.repo.FaceBeautySource;
|
||||
import com.yunbao.faceunity.repo.LightMakeupSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* DESC:轻美妆业务工厂
|
||||
* Created on 2021/3/3
|
||||
*/
|
||||
public class LightMakeupDataFactory extends AbstractLightMakeupDataFactory {
|
||||
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
|
||||
|
||||
/* 轻美妆队列 */
|
||||
private ArrayList<LightMakeupBean> lightMakeupBeans;
|
||||
/* 当前轻美妆选中下标 */
|
||||
private int currentLightMakeupIndex;
|
||||
|
||||
|
||||
public LightMakeupDataFactory(int index) {
|
||||
currentLightMakeupIndex = index;
|
||||
lightMakeupBeans = LightMakeupSource.buildLightMakeup();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取轻美妆队列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<LightMakeupBean> getLightMakeUpBeans() {
|
||||
return lightMakeupBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取轻美妆下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentLightMakeupIndex() {
|
||||
return currentLightMakeupIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置轻美妆下标
|
||||
*
|
||||
* @param currentLightMakeupIndex
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentLightMakeupIndex(int currentLightMakeupIndex) {
|
||||
this.currentLightMakeupIndex = currentLightMakeupIndex;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 切换轻美妆
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
@Override
|
||||
public void onLightMakeupSelected(LightMakeupBean data) {
|
||||
if (data.getKey() == null) {
|
||||
mFURenderKit.setLightMakeup(null);
|
||||
} else {
|
||||
Runnable runnable = LightMakeupSource.LightMakeupParams.get(data.getKey());
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
onLightMakeupIntensityChanged(data.getIntensity());
|
||||
}
|
||||
if (mFURenderKit.getFaceBeauty() != null) {
|
||||
mFURenderKit.getFaceBeauty().setFilterName(data.getFilterName());
|
||||
mFURenderKit.getFaceBeauty().setFilterIntensity(data.getFilterIntensity());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改强度
|
||||
*
|
||||
* @param intensity
|
||||
*/
|
||||
@Override
|
||||
public void onLightMakeupIntensityChanged(double intensity) {
|
||||
if (mFURenderKit.getLightMakeup() != null) {
|
||||
mFURenderKit.getLightMakeup().setMakeupIntensity(intensity);
|
||||
}
|
||||
if (mFURenderKit.getFaceBeauty() != null) {
|
||||
mFURenderKit.getFaceBeauty().setFilterIntensity(intensity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFURenderKit.setFaceBeauty(FaceBeautySource.clone(FaceBeautyDataFactory.faceBeauty));
|
||||
FUAIKit.getInstance().setMaxFaces(4);
|
||||
LightMakeupBean lightMakeupBean = lightMakeupBeans.get(currentLightMakeupIndex);
|
||||
onLightMakeupSelected(lightMakeupBean);
|
||||
|
||||
if (FaceUnityConfig.IS_OPEN_LAND_MARK) {
|
||||
ExpressionRecognition expressionRecognition = new ExpressionRecognition(new FUBundleData(FaceUnityConfig.BUNDLE_LANDMARKS));
|
||||
expressionRecognition.setLandmarksType(FUAITypeEnum.FUAITYPE_FACELANDMARKS239);
|
||||
mFURenderKit.getPropContainer().addProp(expressionRecognition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,853 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
|
||||
import static com.yunbao.faceunity.repo.MakeupSource.*;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.entity.FUColorRGBData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.makeup.Makeup;
|
||||
import com.faceunity.core.model.makeup.MakeupLipEnum;
|
||||
|
||||
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
|
||||
import com.faceunity.core.utils.DecimalUtils;
|
||||
import com.yunbao.faceunity.entity.MakeupCombinationBean;
|
||||
import com.yunbao.faceunity.entity.MakeupCustomBean;
|
||||
import com.yunbao.faceunity.entity.MakeupCustomClassBean;
|
||||
import com.yunbao.faceunity.infe.AbstractMakeupDataFactory;
|
||||
import com.yunbao.faceunity.repo.FaceBeautySource;
|
||||
import com.yunbao.faceunity.repo.MakeupSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* DESC:美妆业务工厂
|
||||
* Created on 2021/3/1
|
||||
*/
|
||||
public class MakeupDataFactory extends AbstractMakeupDataFactory {
|
||||
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
|
||||
/*组合妆容列表*/
|
||||
private ArrayList<MakeupCombinationBean> makeupCombinations;
|
||||
/*组合妆容当前下标*/
|
||||
private int currentCombinationIndex;//-1:自定义
|
||||
/*美妆数据模型*/
|
||||
private Makeup currentMakeup;
|
||||
/*当前滤镜*/
|
||||
private String currentFilterName;
|
||||
/*当前滤镜*/
|
||||
private Double currentFilterIntensity;
|
||||
|
||||
|
||||
private LinkedHashMap<String, ArrayList<double[]>> mMakeUpColorMap;//美妆颜色表
|
||||
|
||||
private HashMap<String, Integer> mCustomIndexMap = new HashMap<>();//key:美妆类别 value:当前美妆子项选中下标 默认0
|
||||
private HashMap<String, Double> mCustomIntensityMap = new HashMap<>();//key:美妆类别_子项下标 value:当前美妆选中子项的妆容强度 默认1.0
|
||||
private HashMap<String, Integer> mCustomColorIndexMap = new HashMap<>();//key:美妆类别_子项下标 value:当前美妆选中子项的颜色下标 默认3
|
||||
|
||||
|
||||
public MakeupDataFactory(int index) {
|
||||
makeupCombinations = MakeupSource.buildCombinations();
|
||||
mMakeUpColorMap = MakeupSource.buildMakeUpColorMap();
|
||||
currentCombinationIndex = index;
|
||||
currentFilterName = makeupCombinations.get(index).getFilterName();
|
||||
currentFilterIntensity = makeupCombinations.get(index).getFilterIntensity();
|
||||
currentMakeup = MakeupSource.getMakeupModel(makeupCombinations.get(currentCombinationIndex)); // 当前生效模型
|
||||
}
|
||||
|
||||
//region 组合妆
|
||||
|
||||
/**
|
||||
* 获取当前组合妆容列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@NonNull
|
||||
public ArrayList<MakeupCombinationBean> getMakeupCombinations() {
|
||||
return makeupCombinations;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前组合妆容下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentCombinationIndex() {
|
||||
return currentCombinationIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置组合妆容下标
|
||||
*
|
||||
* @param currentCombinationIndex
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentCombinationIndex(int currentCombinationIndex) {
|
||||
this.currentCombinationIndex = currentCombinationIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换组合妆容
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void onMakeupCombinationSelected(MakeupCombinationBean bean) {
|
||||
currentFilterName = bean.getFilterName();
|
||||
currentFilterIntensity = bean.getFilterIntensity();
|
||||
if (mFURenderKit.getFaceBeauty() != null) {
|
||||
mFURenderKit.getFaceBeauty().setFilterName(currentFilterName);
|
||||
mFURenderKit.getFaceBeauty().setFilterIntensity(currentFilterIntensity);
|
||||
}
|
||||
currentMakeup = MakeupSource.getMakeupModel(bean);
|
||||
mFURenderKit.setMakeup(currentMakeup);
|
||||
if (!currentMakeup.getControlBundle().getPath().equals(FaceUnityConfig.BUNDLE_FACE_MAKEUP))
|
||||
currentMakeup.setFilterIntensity(currentFilterIntensity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换美妆模型整体强度
|
||||
*
|
||||
* @param intensity
|
||||
*/
|
||||
@Override
|
||||
public void updateCombinationIntensity(double intensity) {
|
||||
currentMakeup.setMakeupIntensity(intensity);
|
||||
currentFilterIntensity = intensity;
|
||||
if (mFURenderKit.getFaceBeauty() != null) {
|
||||
mFURenderKit.getFaceBeauty().setFilterIntensity(currentFilterIntensity);
|
||||
}
|
||||
|
||||
if (!currentMakeup.getControlBundle().getPath().equals(FaceUnityConfig.BUNDLE_FACE_MAKEUP))
|
||||
currentMakeup.setFilterIntensity(currentFilterIntensity);
|
||||
}
|
||||
|
||||
|
||||
//endregion 组合妆
|
||||
|
||||
//region 子美妆
|
||||
|
||||
|
||||
/**
|
||||
* 获取子妆类别列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<MakeupCustomClassBean> getMakeupCustomClass() {
|
||||
return MakeupSource.buildCustomClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子妆列表参数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public LinkedHashMap<String, ArrayList<MakeupCustomBean>> getMakeupCustomItemParams() {
|
||||
return MakeupSource.buildCustomItemParams(mMakeUpColorMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置子妆强度
|
||||
*
|
||||
* @param key
|
||||
* @param current
|
||||
* @param intensity
|
||||
*/
|
||||
@Override
|
||||
public void updateCustomItemIntensity(String key, int current, double intensity) {
|
||||
if (key.equals(FACE_MAKEUP_TYPE_FOUNDATION)) {
|
||||
currentMakeup.setFoundationIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_LIP_STICK)) {
|
||||
currentMakeup.setLipIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_BLUSHER)) {
|
||||
currentMakeup.setBlusherIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_BROW)) {
|
||||
currentMakeup.setEyeBrowIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_SHADOW)) {
|
||||
currentMakeup.setEyeShadowIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LINER)) {
|
||||
currentMakeup.setEyeLineIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LASH)) {
|
||||
currentMakeup.setEyeLashIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_HIGH_LIGHT)) {
|
||||
currentMakeup.setHeightLightIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_SHADOW)) {
|
||||
currentMakeup.setShadowIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_PUPIL)) {
|
||||
currentMakeup.setPupilIntensity(intensity);
|
||||
}
|
||||
mCustomIntensityMap.put(key + "_" + current, intensity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换子妆单项
|
||||
*
|
||||
* @param key 子妆类别
|
||||
* @param index 选中下标
|
||||
*/
|
||||
@Override
|
||||
public void onCustomBeanSelected(String key, int index) {
|
||||
String itemDir = FaceUnityConfig.MAKEUP_RESOURCE_ITEM_BUNDLE_DIR;
|
||||
mCustomIndexMap.put(key, index);
|
||||
if (key.equals(FACE_MAKEUP_TYPE_FOUNDATION)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setFoundationIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setFoundationBundle(new FUBundleData(itemDir + "mu_style_foundation_01.bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_FOUNDATION + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_FOUNDATION + "_" + index);
|
||||
}
|
||||
currentMakeup.setFoundationIntensity((intensity));
|
||||
updateCustomColor(key, index + 2);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_foundation_01").get(index + 2);
|
||||
currentMakeup.setFoundationColor(buildFUColorRGBData(color));
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_LIP_STICK)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setLipIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setLipBundle(new FUBundleData(itemDir + "mu_style_lip_0" + index + ".bundle"));
|
||||
switch (index) {
|
||||
case 1:
|
||||
currentMakeup.setLipType(MakeupLipEnum.FOG);
|
||||
currentMakeup.setEnableTwoLipColor(false);
|
||||
currentMakeup.setLipHighLightEnable(false);
|
||||
currentMakeup.setLipHighLightStrength(0.0);
|
||||
break;
|
||||
case 2:
|
||||
currentMakeup.setLipType(MakeupLipEnum.MOIST);
|
||||
currentMakeup.setEnableTwoLipColor(false);
|
||||
currentMakeup.setLipHighLightEnable(false);
|
||||
currentMakeup.setLipHighLightStrength(0.0);
|
||||
break;
|
||||
case 3:
|
||||
currentMakeup.setLipType(MakeupLipEnum.WATER);
|
||||
currentMakeup.setEnableTwoLipColor(false);
|
||||
currentMakeup.setLipHighLightEnable(true);
|
||||
currentMakeup.setLipHighLightStrength(0.8);
|
||||
break;
|
||||
case 4:
|
||||
currentMakeup.setLipType(MakeupLipEnum.PEARL);
|
||||
currentMakeup.setEnableTwoLipColor(false);
|
||||
currentMakeup.setLipHighLightEnable(false);
|
||||
currentMakeup.setLipHighLightStrength(0.0);
|
||||
break;
|
||||
case 5:
|
||||
currentMakeup.setLipType(MakeupLipEnum.FOG);
|
||||
currentMakeup.setEnableTwoLipColor(true);
|
||||
currentMakeup.setLipHighLightEnable(false);
|
||||
currentMakeup.setLipHighLightStrength(0.0);
|
||||
currentMakeup.setLipColor2(new FUColorRGBData(0.0, 0.0, 0.0, 0.0));
|
||||
break;
|
||||
}
|
||||
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_LIP_STICK + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_LIP_STICK + "_" + index);
|
||||
}
|
||||
currentMakeup.setLipIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_LIP_STICK + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_LIP_STICK + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_BLUSHER)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setBlusherIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setBlusherBundle(new FUBundleData(itemDir + "mu_style_blush_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_BLUSHER + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_BLUSHER + "_" + index);
|
||||
}
|
||||
currentMakeup.setBlusherIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_BLUSHER + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_BLUSHER + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_BROW)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setEyeBrowIntensity(0.0);
|
||||
currentMakeup.setEnableBrowWarp(false);
|
||||
} else {
|
||||
currentMakeup.setEnableBrowWarp(false);
|
||||
currentMakeup.setEyeBrowBundle(new FUBundleData(itemDir + "mu_style_eyebrow_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_BROW + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_BROW + "_" + index);
|
||||
}
|
||||
currentMakeup.setEyeBrowIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_EYE_BROW + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_EYE_BROW + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_SHADOW)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setEyeShadowIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setEyeShadowBundle(new FUBundleData(itemDir + "mu_style_eyeshadow_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + index);
|
||||
}
|
||||
currentMakeup.setEyeShadowIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LINER)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setEyeLineIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setEyeLinerBundle(new FUBundleData(itemDir + "mu_style_eyeliner_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_LINER + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_LINER + "_" + index);
|
||||
}
|
||||
currentMakeup.setEyeLineIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_EYE_LINER + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_EYE_LINER + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LASH)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setEyeLashIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setEyeLashBundle(new FUBundleData(itemDir + "mu_style_eyelash_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_LASH + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_LASH + "_" + index);
|
||||
}
|
||||
currentMakeup.setEyeLashIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_EYE_LASH + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_EYE_LASH + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_HIGH_LIGHT)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setHeightLightIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setHighLightBundle(new FUBundleData(itemDir + "mu_style_highlight_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + index);
|
||||
}
|
||||
currentMakeup.setHeightLightIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_SHADOW)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setShadowIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setShadowBundle(new FUBundleData(itemDir + "mu_style_contour_01.bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_SHADOW + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_SHADOW + "_" + index);
|
||||
}
|
||||
currentMakeup.setShadowIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_SHADOW + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_SHADOW + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_PUPIL)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setPupilIntensity(0.0);
|
||||
} else {
|
||||
if (index == 1) {
|
||||
currentMakeup.setPupilBundle(new FUBundleData(itemDir + "mu_style_eyepupil_01.bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index);
|
||||
}
|
||||
currentMakeup.setPupilIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
} else {
|
||||
currentMakeup.setPupilBundle(new FUBundleData(itemDir + "mu_style_eyepupil_0" + (index + 1) + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index);
|
||||
}
|
||||
currentMakeup.setPupilIntensity((intensity));
|
||||
currentMakeup.setPupilColor(buildFUColorRGBData(new double[]{0.0, 0.0, 0.0, 0.0}));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置子妆颜色值
|
||||
*
|
||||
* @param key 类别关键字
|
||||
* @param index 颜色下标
|
||||
*/
|
||||
@Override
|
||||
public void updateCustomColor(String key, int index) {
|
||||
int current = mCustomIndexMap.containsKey(key) ? mCustomIndexMap.get(key) : 0;
|
||||
if (key.equals(FACE_MAKEUP_TYPE_LIP_STICK)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_LIP_STICK + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_lip_01").get(index);
|
||||
if (current == 3)
|
||||
currentMakeup.setLipColorV2(buildFUColorRGBData(color));
|
||||
else
|
||||
currentMakeup.setLipColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_BLUSHER)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_BLUSHER + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_blush_0" + current).get(index);
|
||||
currentMakeup.setBlusherColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_BROW)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_BROW + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_eyebrow_01").get(index);
|
||||
currentMakeup.setEyeBrowColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_SHADOW)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_eyeshadow_0" + current).get(index);
|
||||
currentMakeup.setEyeShadowColor(new FUColorRGBData(color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255));
|
||||
currentMakeup.setEyeShadowColor2(new FUColorRGBData(color[4] * 255, color[5] * 255, color[6] * 255, color[7] * 255));
|
||||
currentMakeup.setEyeShadowColor3(new FUColorRGBData(color[8] * 255, color[9] * 255, color[10] * 255, color[11] * 255));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LINER)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_LINER + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_eyeliner_0" + current).get(index);
|
||||
currentMakeup.setEyeLinerColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LASH)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_LASH + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_eyelash_0" + current).get(index);
|
||||
currentMakeup.setEyeLashColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_HIGH_LIGHT)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_highlight_0" + current).get(index);
|
||||
currentMakeup.setHighLightColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_SHADOW)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_SHADOW + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_contour_01").get(index);
|
||||
currentMakeup.setShadowColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_PUPIL)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_eyepupil_01").get(index);
|
||||
currentMakeup.setPupilColor(buildFUColorRGBData(color));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//endregion 子美妆
|
||||
|
||||
//region 其他
|
||||
|
||||
/**
|
||||
* 进入自定义美妆,模型分析
|
||||
*/
|
||||
@Override
|
||||
public void enterCustomMakeup() {
|
||||
mCustomIndexMap.clear();
|
||||
mCustomColorIndexMap.clear();
|
||||
mCustomIntensityMap.clear();
|
||||
double makeupIntensity = currentMakeup.getMakeupIntensity();
|
||||
/*粉底*/
|
||||
if (currentMakeup.getFoundationIntensity() != 0.0) {
|
||||
double intensity = currentMakeup.getFoundationIntensity() * makeupIntensity;
|
||||
currentMakeup.setFoundationIntensity(intensity);
|
||||
double[] array = currentMakeup.getFoundationColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_foundation_01");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(array, list.get(i))) {
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_FOUNDATION, i - 2);
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_FOUNDATION + "_" + (i - 2), intensity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*口红*/
|
||||
if (currentMakeup.getLipIntensity() != 0.0) {
|
||||
double intensity = currentMakeup.getLipIntensity() * makeupIntensity;
|
||||
currentMakeup.setLipIntensity(intensity);
|
||||
int current = 0;
|
||||
switch (currentMakeup.getLipType()) {
|
||||
case MakeupLipEnum.FOG:
|
||||
if (currentMakeup.getEnableTwoLipColor()) {
|
||||
current = 5;
|
||||
} else {
|
||||
current = 1;
|
||||
}
|
||||
break;
|
||||
case MakeupLipEnum.MOIST:
|
||||
current = 3;
|
||||
break;
|
||||
case MakeupLipEnum.PEARL:
|
||||
current = 4;
|
||||
break;
|
||||
case MakeupLipEnum.WATER:
|
||||
current = 2;
|
||||
break;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_LIP_STICK, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray;
|
||||
if (currentMakeup.getLipType() == MakeupLipEnum.WATER) {
|
||||
colorArray = currentMakeup.getLipColorV2().toScaleColorArray();
|
||||
} else {
|
||||
colorArray = currentMakeup.getLipColor().toScaleColorArray();
|
||||
}
|
||||
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_lip_01");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_LIP_STICK + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_LIP_STICK + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/*腮红*/
|
||||
if (currentMakeup.getBlusherIntensity() != 0.0 && currentMakeup.getBlusherBundle() != null) {
|
||||
double intensity = currentMakeup.getBlusherIntensity() * makeupIntensity;
|
||||
currentMakeup.setBlusherIntensity(intensity);
|
||||
String path = currentMakeup.getBlusherBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_blush_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_blush_02.bundle")) {
|
||||
current = 2;
|
||||
} else if (path.endsWith("mu_style_blush_03.bundle")) {
|
||||
current = 3;
|
||||
} else if (path.endsWith("mu_style_blush_04.bundle")) {
|
||||
current = 4;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_BLUSHER, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getBlusherColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_blush_0" + current);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_BLUSHER + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_BLUSHER + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/*眉毛*/
|
||||
if (currentMakeup.getEyeBrowIntensity() != 0.0) {
|
||||
double intensity = currentMakeup.getEyeBrowIntensity() * makeupIntensity;
|
||||
currentMakeup.setEyeBrowIntensity(intensity);
|
||||
int current = 0;
|
||||
if (currentMakeup.getEyeBrowBundle() != null && currentMakeup.getEyeBrowBundle().getPath() != null) {
|
||||
String bundlePath = currentMakeup.getEyeBrowBundle().getPath();
|
||||
int spotIndex = bundlePath.lastIndexOf(".");
|
||||
String index = bundlePath.substring(spotIndex - 1, spotIndex);
|
||||
current = Integer.valueOf(index);
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_EYE_BROW, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getEyeBrowColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_eyebrow_01");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_BROW + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_EYE_BROW + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/*眼影*/
|
||||
if (currentMakeup.getEyeShadowIntensity() != 0.0 && currentMakeup.getEyeShadowBundle() != null) {
|
||||
double intensity = currentMakeup.getEyeShadowIntensity() * makeupIntensity;
|
||||
currentMakeup.setEyeShadowIntensity(intensity);
|
||||
String path = currentMakeup.getEyeShadowBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_eyeshadow_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_eyeshadow_02.bundle")) {
|
||||
current = 2;
|
||||
} else if (path.endsWith("mu_style_eyeshadow_03.bundle")) {
|
||||
current = 3;
|
||||
} else if (path.endsWith("mu_style_eyeshadow_04.bundle")) {
|
||||
current = 4;
|
||||
} else if (path.endsWith("mu_style_eyeshadow_05.bundle")) {
|
||||
current = 5;
|
||||
} else if (path.endsWith("mu_style_eyeshadow_06.bundle")) {
|
||||
current = 6;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_EYE_SHADOW, current);
|
||||
if (current != 0) {
|
||||
double[] array = new double[12];
|
||||
double[] color1 = currentMakeup.getEyeShadowColor().toScaleColorArray();
|
||||
double[] color2 = currentMakeup.getEyeShadowColor2().toScaleColorArray();
|
||||
double[] color3 = currentMakeup.getEyeShadowColor3().toScaleColorArray();
|
||||
System.arraycopy(color1, 0, array, 0, color1.length);
|
||||
System.arraycopy(color2, 0, array, 4, color2.length);
|
||||
System.arraycopy(color3, 0, array, 8, color3.length);
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_eyeshadow_0" + current);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(array, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/*眼线*/
|
||||
if (currentMakeup.getEyeLineIntensity() != 0.0 && currentMakeup.getEyeLinerBundle() != null) {
|
||||
double intensity = currentMakeup.getEyeLineIntensity() * makeupIntensity;
|
||||
currentMakeup.setEyeLineIntensity(intensity);
|
||||
String path = currentMakeup.getEyeLinerBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_eyeliner_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_eyeliner_02.bundle")) {
|
||||
current = 2;
|
||||
} else if (path.endsWith("mu_style_eyeliner_03.bundle")) {
|
||||
current = 3;
|
||||
} else if (path.endsWith("mu_style_eyeliner_04.bundle")) {
|
||||
current = 4;
|
||||
} else if (path.endsWith("mu_style_eyeliner_05.bundle")) {
|
||||
current = 5;
|
||||
} else if (path.endsWith("mu_style_eyeliner_06.bundle")) {
|
||||
current = 6;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_EYE_LINER, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getEyeLinerColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_eyeliner_0" + current);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_LINER + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_EYE_LINER + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/* 睫毛*/
|
||||
if (currentMakeup.getEyeLashIntensity() != 0.0 && currentMakeup.getEyeLashBundle() != null) {
|
||||
double intensity = currentMakeup.getEyeLashIntensity() * makeupIntensity;
|
||||
currentMakeup.setEyeLashIntensity(intensity);
|
||||
String path = currentMakeup.getEyeLashBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_eyelash_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_eyelash_02.bundle")) {
|
||||
current = 2;
|
||||
} else if (path.endsWith("mu_style_eyelash_03.bundle")) {
|
||||
current = 3;
|
||||
} else if (path.endsWith("mu_style_eyelash_04.bundle")) {
|
||||
current = 4;
|
||||
} else if (path.endsWith("mu_style_eyelash_05.bundle")) {
|
||||
current = 5;
|
||||
} else if (path.endsWith("mu_style_eyelash_06.bundle")) {
|
||||
current = 6;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_EYE_LASH, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getEyeLashColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_eyelash_0" + current);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_LASH + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_EYE_LASH + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/* 高光*/
|
||||
if (currentMakeup.getHeightLightIntensity() != 0.0 && currentMakeup.getHighLightBundle() != null) {
|
||||
double intensity = currentMakeup.getHeightLightIntensity() * makeupIntensity;
|
||||
currentMakeup.setHeightLightIntensity(intensity);
|
||||
String path = currentMakeup.getHighLightBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_highlight_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_highlight_02.bundle")) {
|
||||
current = 2;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_HIGH_LIGHT, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getHighLightColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_highlight_0" + current);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/* 阴影*/
|
||||
if (currentMakeup.getShadowIntensity() != 0.0 && currentMakeup.getShadowBundle() != null) {
|
||||
double intensity = currentMakeup.getShadowIntensity() * makeupIntensity;
|
||||
currentMakeup.setShadowIntensity(intensity);
|
||||
String path = currentMakeup.getShadowBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_contour_01.bundle")) {
|
||||
current = 1;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_SHADOW, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getShadowColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_contour_01");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_SHADOW + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_SHADOW + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/* 美瞳*/
|
||||
if (currentMakeup.getPupilIntensity() != 0.0 && currentMakeup.getPupilBundle() != null) {
|
||||
double intensity = currentMakeup.getPupilIntensity() * makeupIntensity;
|
||||
currentMakeup.setPupilIntensity(intensity);
|
||||
String path = currentMakeup.getPupilBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_eyepupil_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_eyepupil_03.bundle")) {
|
||||
current = 2;
|
||||
} else if (path.endsWith("mu_style_eyepupil_04.bundle")) {
|
||||
current = 3;
|
||||
} else if (path.endsWith("mu_style_eyepupil_05.bundle")) {
|
||||
current = 4;
|
||||
} else if (path.endsWith("mu_style_eyepupil_06.bundle")) {
|
||||
current = 5;
|
||||
} else if (path.endsWith("mu_style_eyepupil_07.bundle")) {
|
||||
current = 6;
|
||||
} else if (path.endsWith("mu_style_eyepupil_08.bundle")) {
|
||||
current = 7;
|
||||
} else if (path.endsWith("mu_style_eyepupil_09.bundle")) {
|
||||
current = 8;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_EYE_PUPIL, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getPupilColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_eyepupil_01");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
currentMakeup.setMakeupIntensity(1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 或当单项列表当前下标
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentCustomItemIndex(String key) {
|
||||
if (mCustomIndexMap.containsKey(key)) {
|
||||
return mCustomIndexMap.get(key);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前单项颜色下标
|
||||
*
|
||||
* @param key
|
||||
* @param current
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentCustomColorIndex(String key, int current) {
|
||||
if (mCustomColorIndexMap.containsKey(key + "_" + current)) {
|
||||
return mCustomColorIndexMap.get(key + "_" + current);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前单项强度
|
||||
*
|
||||
* @param key
|
||||
* @param current
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double getCurrentCustomIntensity(String key, int current) {
|
||||
if (mCustomIntensityMap.containsKey(key + "_" + current)) {
|
||||
return mCustomIntensityMap.get(key + "_" + current);
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFURenderKit.setFaceBeauty(FaceBeautySource.clone(FaceBeautyDataFactory.faceBeauty));
|
||||
mFURenderKit.getFaceBeauty().setFilterName(currentFilterName);
|
||||
mFURenderKit.getFaceBeauty().setFilterIntensity(currentFilterIntensity);
|
||||
if (!currentMakeup.getControlBundle().getPath().equals(FaceUnityConfig.BUNDLE_FACE_MAKEUP))
|
||||
currentMakeup.setFilterIntensity(currentFilterIntensity);
|
||||
FUAIKit.getInstance().setMaxFaces(4);
|
||||
mFURenderKit.setMakeup(currentMakeup);
|
||||
|
||||
//特殊有一些需要设置图层混合模式的 04双色眼影3(第2层眼影的混合模式 == 1) 06三色眼影2(第3层眼影的混合模式 == 1)
|
||||
if (currentMakeup.getEyeShadowBundle() != null && ("mu_style_eyeshadow_0" + 4).equals(currentMakeup.getEyeShadowBundle().getName()))
|
||||
currentMakeup.setEyeShadowTexBlend2(1);
|
||||
else if (currentMakeup.getEyeShadowBundle() != null && ("mu_style_eyeshadow_0" + 6).equals(currentMakeup.getEyeShadowBundle().getName()))
|
||||
currentMakeup.setEyeShadowTexBlend3(1);
|
||||
|
||||
if (FaceUnityConfig.IS_OPEN_LAND_MARK) {
|
||||
ExpressionRecognition expressionRecognition = new ExpressionRecognition(new FUBundleData(FaceUnityConfig.BUNDLE_LANDMARKS));
|
||||
expressionRecognition.setLandmarksType(FUAITypeEnum.FUAITYPE_FACELANDMARKS239);
|
||||
mFURenderKit.getPropContainer().addProp(expressionRecognition);
|
||||
}
|
||||
}
|
||||
public void clearAll(){
|
||||
currentMakeup = new Makeup(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_MAKEUP));
|
||||
mFURenderKit.setMakeup(currentMakeup);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.prop.Prop;
|
||||
import com.faceunity.core.model.prop.arMask.ARMask;
|
||||
import com.faceunity.core.model.prop.bigHead.BigHead;
|
||||
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
|
||||
import com.faceunity.core.model.prop.faceWarp.FaceWarp;
|
||||
import com.faceunity.core.model.prop.gesture.GestureRecognition;
|
||||
import com.faceunity.core.model.prop.sticker.Sticker;
|
||||
import com.yunbao.faceunity.entity.FunctionEnum;
|
||||
import com.yunbao.faceunity.entity.PropBean;
|
||||
import com.yunbao.faceunity.infe.AbstractPropDataFactory;
|
||||
import com.yunbao.faceunity.repo.PropSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DESC:道具业务工厂:道具贴图、AR面具、搞笑大头、表情识别、哈哈镜、手势识别
|
||||
* Created on 2021/3/2
|
||||
*/
|
||||
public class PropDataFactory extends AbstractPropDataFactory {
|
||||
|
||||
public interface PropListener {
|
||||
|
||||
void onItemSelected(PropBean bean);
|
||||
|
||||
}
|
||||
|
||||
/*渲染控制器*/
|
||||
private final FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
/*道具列表*/
|
||||
private final ArrayList<PropBean> propBeans;
|
||||
|
||||
/*默认选中下标*/
|
||||
private int currentPropIndex;
|
||||
/*当前道具*/
|
||||
public Prop currentProp;
|
||||
/*回调接口*/
|
||||
private final PropListener mPropListener;
|
||||
/*道具类型*/
|
||||
private int propType;
|
||||
|
||||
|
||||
/**
|
||||
* @param listener 回调接口
|
||||
* @param type 道具类型
|
||||
* @param index 默认选中下标
|
||||
*/
|
||||
public PropDataFactory(PropListener listener, int type, int index) {
|
||||
mPropListener = listener;
|
||||
propType = type;
|
||||
currentPropIndex = index;
|
||||
propBeans = PropSource.buildPropBeans(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前选中下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentPropIndex() {
|
||||
return currentPropIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前选中下标
|
||||
*
|
||||
* @param currentPropIndex
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentPropIndex(int currentPropIndex) {
|
||||
this.currentPropIndex = currentPropIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取道具队列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@NonNull
|
||||
public ArrayList<PropBean> getPropBeans() {
|
||||
return propBeans;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置效果
|
||||
*/
|
||||
@Override
|
||||
public void onItemSelected(PropBean bean) {
|
||||
onPropSelected(bean);
|
||||
mPropListener.onItemSelected(bean);
|
||||
}
|
||||
|
||||
public void setPropType(int propType) {
|
||||
this.propType = propType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 其他道具
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
private void onPropSelected(PropBean bean) {
|
||||
String path = bean.getPath();
|
||||
if (path == null || path.trim().length() == 0) {
|
||||
mFURenderKit.getPropContainer().removeAllProp();
|
||||
currentProp = null;
|
||||
return;
|
||||
}
|
||||
Prop prop = null;
|
||||
switch (propType) {
|
||||
case FunctionEnum.STICKER:
|
||||
prop = new Sticker(new FUBundleData(path));
|
||||
break;
|
||||
case FunctionEnum.AR_MASK:
|
||||
prop = new ARMask(new FUBundleData(path));
|
||||
break;
|
||||
case FunctionEnum.BIG_HEAD:
|
||||
prop = new BigHead(new FUBundleData(path));
|
||||
break;
|
||||
case FunctionEnum.EXPRESSION_RECOGNITION:
|
||||
prop = new ExpressionRecognition(new FUBundleData(path));
|
||||
break;
|
||||
case FunctionEnum.FACE_WARP:
|
||||
prop = new FaceWarp(new FUBundleData(path));
|
||||
break;
|
||||
case FunctionEnum.GESTURE_RECOGNITION:
|
||||
prop = new GestureRecognition(new FUBundleData(path));
|
||||
break;
|
||||
}
|
||||
mFURenderKit.getPropContainer().replaceProp(currentProp, prop);
|
||||
currentProp = prop;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
if (propType == FunctionEnum.GESTURE_RECOGNITION) {
|
||||
FUAIKit.getInstance().loadAIProcessor(FaceUnityConfig.BUNDLE_AI_HAND, FUAITypeEnum.FUAITYPE_HANDGESTURE);
|
||||
}
|
||||
if (propType == FunctionEnum.BIG_HEAD) {
|
||||
FUAIKit.getInstance().setMaxFaces(1);
|
||||
} else {
|
||||
FUAIKit.getInstance().setMaxFaces(4);
|
||||
}
|
||||
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
PropBean propBean = propBeans.get(currentPropIndex);
|
||||
onItemSelected(propBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束需要释放AI驱动
|
||||
*/
|
||||
public void releaseAIProcessor() {
|
||||
if (propType == FunctionEnum.GESTURE_RECOGNITION) {
|
||||
FUAIKit.getInstance().releaseAIProcessor(FUAITypeEnum.FUAITYPE_HANDGESTURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.yunbao.faceunity.entity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
|
||||
public class AnimationFilterBean extends BaseBean {
|
||||
private int iconId;
|
||||
private int style=0;
|
||||
|
||||
public AnimationFilterBean(int iconId, int style) {
|
||||
this.iconId = iconId;
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public int getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
public void setStyle(int style) {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public int getIconId() {
|
||||
return iconId;
|
||||
}
|
||||
|
||||
public void setIconId(int iconId) {
|
||||
this.iconId = iconId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getKey() {
|
||||
return style+"";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDesRes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageRes() {
|
||||
return iconId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanType() {
|
||||
return FaceParam.FACE_ANIM;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelAttributeData getModelAttributeData() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.yunbao.faceunity.entity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
|
||||
/**
|
||||
* 道具
|
||||
* @property iconId Int 图标
|
||||
* @property path String? Animoji 道具路径
|
||||
* @constructor
|
||||
*/
|
||||
public class AnimojiBean extends BaseBean{
|
||||
private int iconId;
|
||||
private String path;
|
||||
|
||||
public AnimojiBean(int iconId, String path) {
|
||||
this.iconId = iconId;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public int getIconId() {
|
||||
return iconId;
|
||||
}
|
||||
|
||||
public void setIconId(int iconId) {
|
||||
this.iconId = iconId;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getKey() {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDesRes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageRes() {
|
||||
return iconId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanType() {
|
||||
return FaceParam.FACE_ANIMOJI;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelAttributeData getModelAttributeData() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:
|
||||
* Created on 2020/12/4
|
||||
*
|
||||
*/
|
||||
data class AvatarBean(val iconId: Int, val des: String)
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
|
||||
abstract class BaseBean {
|
||||
abstract val key: String
|
||||
abstract val desRes: Int
|
||||
abstract val imageRes: Int
|
||||
abstract val beanType: Int
|
||||
|
||||
abstract fun getModelAttributeData(): ModelAttributeData
|
||||
|
||||
open fun getImageUrl():String {
|
||||
return "";
|
||||
}
|
||||
open fun getImageDrawable(): Drawable{
|
||||
return null!!
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:
|
||||
* Created on 2020/12/4
|
||||
*
|
||||
*/
|
||||
|
||||
data class BgSegGreenBackgroundBean(val desRes: Int, val iconRes: Int, val filePath: String? = null)
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:
|
||||
* Created on 2020/12/4
|
||||
*
|
||||
*/
|
||||
|
||||
data class BgSegGreenBean(val key: String, val desRes: Int, val closeRes: Int, val openRes: Int, val type: ButtonType) {
|
||||
enum class ButtonType{
|
||||
NORMAL1_BUTTON,//普通一号按钮
|
||||
NORMAL2_BUTTON,//普通二号按钮
|
||||
BACK_BUTTON,//返回按钮
|
||||
SWITCH_BUTTON//切换按钮,切换整个按钮功能
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:
|
||||
* Created on 2020/12/4
|
||||
*
|
||||
*/
|
||||
|
||||
data class BgSegGreenSafeAreaBean(val iconRes: Int, val type: ButtonType, val filePath: String? = null,val isAssetFile: Boolean = true) {
|
||||
|
||||
constructor(iconRes: Int, type: ButtonType) : this(
|
||||
iconRes,
|
||||
type,
|
||||
null,
|
||||
true
|
||||
)
|
||||
|
||||
constructor(iconRes: Int, type: ButtonType, filePath :String) : this(
|
||||
iconRes,
|
||||
type,
|
||||
filePath,
|
||||
true
|
||||
)
|
||||
enum class ButtonType{
|
||||
NORMAL1_BUTTON,//普通一号按钮,普通安全区域按钮
|
||||
NORMAL2_BUTTON,//普通二号按钮,用于自定义按钮
|
||||
BACK_BUTTON,//返回按钮
|
||||
NONE_BUTTON,//不选择按钮
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.yunbao.faceunity.entity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
import com.yunbao.faceunity.repo.BodyBeautySource;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* DESC:美体
|
||||
* Created on 2021/4/26
|
||||
*/
|
||||
public class BodyBeautyBean extends BaseBean {
|
||||
private String key;//名称标识
|
||||
private int desRes;//描述
|
||||
private int closeRes;//图片
|
||||
private int openRes;//图片
|
||||
|
||||
public BodyBeautyBean(String key, int desRes, int closeRes, int openRes) {
|
||||
this.key = key;
|
||||
this.desRes = desRes;
|
||||
this.closeRes = closeRes;
|
||||
this.openRes = openRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public int getDesRes() {
|
||||
return desRes;
|
||||
}
|
||||
|
||||
public void setDesRes(int desRes) {
|
||||
this.desRes = desRes;
|
||||
}
|
||||
|
||||
public int getCloseRes() {
|
||||
return closeRes;
|
||||
}
|
||||
|
||||
public void setCloseRes(int closeRes) {
|
||||
this.closeRes = closeRes;
|
||||
}
|
||||
|
||||
public int getOpenRes() {
|
||||
return openRes;
|
||||
}
|
||||
|
||||
public void setOpenRes(int openRes) {
|
||||
this.openRes = openRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageRes() {
|
||||
return closeRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanType() {
|
||||
return FaceParam.FACE_BEAUTY_BODY;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelAttributeData getModelAttributeData() {
|
||||
return Objects.requireNonNull(BodyBeautySource.buildModelAttributeRange().get(key));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
import com.yunbao.faceunity.data.FaceParam
|
||||
import com.yunbao.faceunity.repo.FaceBeautySource
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @property key String 名称标识
|
||||
* @property desRes Int 描述
|
||||
* @property closeRes Int 图片
|
||||
* @property openRes Int 图片
|
||||
* @property buttonType 按钮类型
|
||||
* @constructor
|
||||
*/
|
||||
data class FaceBeautyBean(
|
||||
override val key: String,
|
||||
override val desRes: Int,
|
||||
val closeRes: Int,
|
||||
val openRes: Int,
|
||||
val toastDesRes: Int,
|
||||
val canUseFunction: Boolean = true,
|
||||
val buttonType: ButtonType = ButtonType.NORMAL_BUTTON//定义一项按钮功能 普通按钮 返回按钮 子项按钮
|
||||
, override val beanType: Int
|
||||
, override val imageRes: Int
|
||||
) : BaseBean() {
|
||||
constructor(key: String, desRes: Int, closeRes: Int, openRes: Int) : this(
|
||||
key,
|
||||
desRes,
|
||||
closeRes,
|
||||
openRes,
|
||||
0,
|
||||
true,
|
||||
ButtonType.NORMAL_BUTTON,
|
||||
FaceParam.FACE_BEAUTY_SKIN,
|
||||
closeRes
|
||||
)
|
||||
|
||||
constructor(
|
||||
key: String,
|
||||
desRes: Int,
|
||||
closeRes: Int,
|
||||
openRes: Int,
|
||||
toastDesRes: Int,
|
||||
canUseFunction: Boolean
|
||||
) : this(
|
||||
key,
|
||||
desRes,
|
||||
closeRes,
|
||||
openRes,
|
||||
toastDesRes,
|
||||
canUseFunction,
|
||||
ButtonType.NORMAL_BUTTON,
|
||||
FaceParam.FACE_BEAUTY_SKIN,
|
||||
closeRes
|
||||
)
|
||||
constructor(
|
||||
key: String,
|
||||
desRes: Int,
|
||||
closeRes: Int,
|
||||
openRes: Int,
|
||||
toastDesRes: Int,
|
||||
canUseFunction: Boolean,
|
||||
type:Int
|
||||
):this(
|
||||
key,
|
||||
desRes,
|
||||
closeRes,
|
||||
openRes,
|
||||
toastDesRes,
|
||||
canUseFunction,
|
||||
ButtonType.NORMAL_BUTTON,
|
||||
type,
|
||||
closeRes
|
||||
)
|
||||
|
||||
enum class ButtonType {
|
||||
NORMAL_BUTTON,
|
||||
BACK_BUTTON,
|
||||
SUB_ITEM_BUTTON
|
||||
}
|
||||
|
||||
override fun getModelAttributeData(): ModelAttributeData {
|
||||
return FaceBeautySource.buildModelAttributeRange()?.get(key)!!
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.yunbao.faceunity.entity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
|
||||
/**
|
||||
* DESC:美颜滤镜
|
||||
* Created on 2021/4/26
|
||||
*/
|
||||
public class FaceBeautyFilterBean extends BaseBean {
|
||||
|
||||
private String key;//名称标识
|
||||
private int imageRes;//图片
|
||||
private int desRes;//描述
|
||||
private double intensity = 0.4;//强度
|
||||
|
||||
public FaceBeautyFilterBean(String key, int imageRes, int desRes) {
|
||||
this.key = key;
|
||||
this.imageRes = imageRes;
|
||||
this.desRes = desRes;
|
||||
}
|
||||
|
||||
public FaceBeautyFilterBean(String key, int imageRes, int desRes, double intensity) {
|
||||
this.key = key;
|
||||
this.imageRes = imageRes;
|
||||
this.desRes = desRes;
|
||||
this.intensity = intensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageRes() {
|
||||
return imageRes;
|
||||
}
|
||||
|
||||
public void setImageRes(int imageRes) {
|
||||
this.imageRes = imageRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDesRes() {
|
||||
return desRes;
|
||||
}
|
||||
|
||||
public void setDesRes(int desRes) {
|
||||
this.desRes = desRes;
|
||||
}
|
||||
|
||||
public double getIntensity() {
|
||||
return intensity;
|
||||
}
|
||||
|
||||
public void setIntensity(double intensity) {
|
||||
this.intensity = intensity;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelAttributeData getModelAttributeData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanType() {
|
||||
|
||||
return FaceParam.FACE_BEAUTY_FILTER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
/**
|
||||
* 滤镜
|
||||
* @property key String 名称标识
|
||||
* @property imageRes Int 图片
|
||||
* @property desRes Int 描述
|
||||
* @constructor
|
||||
*/
|
||||
data class FaceBeautyStyleBean(
|
||||
override val key: String,
|
||||
override val imageRes: Int,
|
||||
override val desRes: Int,
|
||||
override val beanType:Int,
|
||||
):
|
||||
BaseBean(){
|
||||
override fun getModelAttributeData(): ModelAttributeData {
|
||||
return null!!
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.yunbao.faceunity.entity;
|
||||
|
||||
public class FunctionEnum {
|
||||
public final static int FACE_BEAUTY = 1;
|
||||
public final static int MAKE_UP = 2;
|
||||
public final static int STICKER = 3;
|
||||
public final static int ANIMOJI = 4;
|
||||
public final static int HAIR_BEAUTY = 5;
|
||||
public final static int LIGHT_MAKEUP = 6;
|
||||
public final static int AR_MASK = 7;
|
||||
public final static int BIG_HEAD = 8;
|
||||
public final static int POSTER_CHANGE = 9;
|
||||
public final static int EXPRESSION_RECOGNITION = 10;
|
||||
public final static int MUSIC_FILTER = 11;
|
||||
public final static int FACE_WARP = 12;
|
||||
public final static int BODY_BEAUTY = 13;
|
||||
public final static int AVATAR = 14;
|
||||
public final static int ACTION_RECOGNITION = 15;
|
||||
public final static int PORTRAIT_SEGMENT = 16;
|
||||
public final static int GESTURE_RECOGNITION = 17;
|
||||
public final static int BG_SEG_GREEN = 18;
|
||||
public final static int HUMAN_OUTLINE = 19;
|
||||
public final static int BG_SEG_CUSTOM = 20;
|
||||
public final static int FINE_STICKER = 21;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.yunbao.faceunity.entity;
|
||||
|
||||
public class LightMakeupBean {
|
||||
int nameRes;
|
||||
int iconRes;
|
||||
String key;
|
||||
double intensity;
|
||||
String filterName;
|
||||
double filterIntensity;
|
||||
|
||||
public LightMakeupBean(int nameRes, int iconRes, String key, double intensity, String filterName, double filterIntensity) {
|
||||
this.nameRes = nameRes;
|
||||
this.iconRes = iconRes;
|
||||
this.key = key;
|
||||
this.intensity = intensity;
|
||||
this.filterName = filterName;
|
||||
this.filterIntensity = filterIntensity;
|
||||
}
|
||||
|
||||
public int getNameRes() {
|
||||
return nameRes;
|
||||
}
|
||||
|
||||
public void setNameRes(int nameRes) {
|
||||
this.nameRes = nameRes;
|
||||
}
|
||||
|
||||
public int getIconRes() {
|
||||
return iconRes;
|
||||
}
|
||||
|
||||
public void setIconRes(int iconRes) {
|
||||
this.iconRes = iconRes;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public double getIntensity() {
|
||||
return intensity;
|
||||
}
|
||||
|
||||
public void setIntensity(double intensity) {
|
||||
this.intensity = intensity;
|
||||
}
|
||||
|
||||
public String getFilterName() {
|
||||
return filterName;
|
||||
}
|
||||
|
||||
public void setFilterName(String filterName) {
|
||||
this.filterName = filterName;
|
||||
}
|
||||
|
||||
public double getFilterIntensity() {
|
||||
return filterIntensity;
|
||||
}
|
||||
|
||||
public void setFilterIntensity(double filterIntensity) {
|
||||
this.filterIntensity = filterIntensity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @property key String 名称标识
|
||||
* @property type TypeEnum 类型
|
||||
* @property imageRes Int 图片
|
||||
* @property desRes Int 描述
|
||||
* @property bundlePath FUBundleData 资源句柄
|
||||
* @property jsonPath String 参数配置路径
|
||||
* @property filterName Double 滤镜
|
||||
* @property filterIntensity Double 滤镜强度
|
||||
* @property filterScale Double scale 标准滤镜比率
|
||||
* @property intensity Double 强度
|
||||
* @property jsonPathParams Double 参数配置缓存
|
||||
* @constructor
|
||||
*/
|
||||
data class MakeupCombinationBean @JvmOverloads constructor(
|
||||
override val key: String,
|
||||
val type: TypeEnum,
|
||||
override val imageRes: Int,
|
||||
override val desRes: Int,
|
||||
val bundlePath: String?,
|
||||
val jsonPath: String,
|
||||
val filterName: String,
|
||||
var filterScale: Double = 1.0,
|
||||
var filterIntensity: Double = 0.7,
|
||||
var intensity: Double = 0.7,
|
||||
var jsonPathParams: LinkedHashMap<String, Any>? = null,
|
||||
override val beanType: Int
|
||||
): BaseBean() {
|
||||
enum class TypeEnum {
|
||||
TYPE_NONE, //无
|
||||
TYPE_DAILY,//日常妆,支持自定义
|
||||
TYPE_THEME_SUB,//主题妆_依附于face_makeup
|
||||
TYPE_THEME_MAIN,//主题妆_替换face_makeup
|
||||
}
|
||||
|
||||
override fun getModelAttributeData(): ModelAttributeData {
|
||||
return null!!
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.yunbao.faceunity.entity;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
/**
|
||||
*
|
||||
* @property nameRes Int 名称
|
||||
* @property drawable Drawable 图片资源
|
||||
* @property doubleArray ArrayList<DoubleArray>? 颜色数组
|
||||
* @constructor
|
||||
*/
|
||||
public class MakeupCustomBean extends BaseBean{
|
||||
private int nameRes;
|
||||
private Drawable drawable;
|
||||
private ArrayList<double[]> doubleArray;
|
||||
private int beanType;
|
||||
|
||||
public MakeupCustomBean(int nameRes, Drawable drawable, ArrayList<double[]> doubleArray,int beanType) {
|
||||
this.nameRes = nameRes;
|
||||
this.drawable = drawable;
|
||||
this.doubleArray = doubleArray;
|
||||
this.beanType=beanType;
|
||||
}
|
||||
|
||||
|
||||
public MakeupCustomBean(int nameRes, Drawable drawable,int beanType) {
|
||||
this.nameRes = nameRes;
|
||||
this.drawable = drawable;
|
||||
this.beanType=beanType;
|
||||
}
|
||||
|
||||
public int getNameRes() {
|
||||
return nameRes;
|
||||
}
|
||||
|
||||
public void setNameRes(int nameRes) {
|
||||
this.nameRes = nameRes;
|
||||
}
|
||||
|
||||
public Drawable getDrawable() {
|
||||
return drawable;
|
||||
}
|
||||
|
||||
public void setDrawable(Drawable drawable) {
|
||||
this.drawable = drawable;
|
||||
}
|
||||
|
||||
public ArrayList<double[]> getDoubleArray() {
|
||||
return doubleArray;
|
||||
}
|
||||
|
||||
public void setDoubleArray(ArrayList<double[]> doubleArray) {
|
||||
this.doubleArray = doubleArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return nameRes+"";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDesRes() {
|
||||
return nameRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageRes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Drawable getImageDrawable() {
|
||||
return drawable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanType() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelAttributeData getModelAttributeData() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.yunbao.faceunity.entity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
|
||||
public class MakeupCustomClassBean extends BaseBean{
|
||||
private int nameRes;
|
||||
private String key;
|
||||
private int beanType;
|
||||
|
||||
public MakeupCustomClassBean(int nameRes, String key, int beanType) {
|
||||
this.nameRes = nameRes;
|
||||
this.key = key;
|
||||
this.beanType = beanType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDesRes() {
|
||||
return nameRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageRes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanType() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelAttributeData getModelAttributeData() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
data class MenuGroupBean(val titleId :Int,val iconId:Int)
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
|
||||
/**
|
||||
* 模型单项补充模型
|
||||
* @property default Double 默认值
|
||||
* @property stand Double 无变化时候的基准值
|
||||
* @property minRange Double 范围最小值
|
||||
* @property maxRange Double 范围最大值
|
||||
* @constructor
|
||||
*/
|
||||
data class ModelAttributeData(val default: Double=0.0, val stand: Double = 0.0, val minRange: Double = 0.0, val maxRange: Double = 1.0)
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.yunbao.faceunity.entity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
|
||||
/**
|
||||
* 道具
|
||||
* @property iconId Int 图标
|
||||
* @property path String 道具路径
|
||||
* @property descId Int 道具提示
|
||||
* @constructor
|
||||
*/
|
||||
public class PropBean extends BaseBean {
|
||||
private int iconId;
|
||||
private String path;
|
||||
private int descId;
|
||||
private int beanType;
|
||||
|
||||
public PropBean(int iconId, String path,int beanType) {
|
||||
this.iconId = iconId;
|
||||
this.path = path;
|
||||
this.beanType=beanType;
|
||||
}
|
||||
|
||||
public PropBean(int iconId, String path, int descId,int beanType) {
|
||||
this.iconId = iconId;
|
||||
this.path = path;
|
||||
this.descId = descId;
|
||||
this.beanType=beanType;
|
||||
}
|
||||
|
||||
public int getIconId() {
|
||||
return iconId;
|
||||
}
|
||||
|
||||
public void setIconId(int iconId) {
|
||||
this.iconId = iconId;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public int getDescId() {
|
||||
return descId;
|
||||
}
|
||||
|
||||
public void setDescId(int descId) {
|
||||
this.descId = descId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getKey() {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDesRes() {
|
||||
return descId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageRes() {
|
||||
return iconId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanType() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelAttributeData getModelAttributeData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.yunbao.faceunity.entity
|
||||
|
||||
/**
|
||||
* 道具
|
||||
* @property iconId Int 图标
|
||||
* @property path String 道具路径
|
||||
* @property descId Int 道具提示
|
||||
* @property descId Int 类型 -2 为添加事件 -1为空 其他多道具类型
|
||||
* @property iconPath 图标路径
|
||||
* @constructor
|
||||
*/
|
||||
data class PropCustomBean @JvmOverloads constructor(
|
||||
val iconId: Int,
|
||||
val path: String?,
|
||||
val type: Int = -1,
|
||||
val descId: Int = 0,
|
||||
val iconPath: String? = null
|
||||
)
|
||||
@@ -0,0 +1,328 @@
|
||||
package com.yunbao.faceunity.entity.net;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author Qinyu on 2021-03-17
|
||||
* @description
|
||||
*/
|
||||
public class FineStickerEntity {
|
||||
/**
|
||||
* count : 2
|
||||
* docs : [{"_id":"6051a0aa6d670000230030c7","index":1,"tool":{"_id":"5f6ae24e570100009e006547","bundle":{"remark":"优化背景分割,提高边缘稳定性,需要SDK v6.2.0支持","uid":"0a176380-b33e-11e9-8e6a-35012f229fc1.bundle","size":3872.85,"name":"hez_ztt_fu.bundle"},"icon":{"remark":"v1.0","uid":"167f72e0-e173-11e8-b908-51298abcbcf5.png","size":61.83,"name":"hez_ztt_fu.png","url":"http://tools-manage.oss-cn-hangzhou.aliyuncs.com/167f72e0-e173-11e8-b908-51298abcbcf5.png?OSSAccessKeyId=LTAIZvD3ylHAD1vH&Expires=1616057194&Signature=4aesuhXnenASOXCQwl0logppBM4%3D"}},"platform":"mobile","tag":"中级道具"},{"_id":"6051a2d36d670000230030c8","index":2,"tool":{"_id":"5f6ae24e570100009e006547","bundle":{"remark":"优化背景分割,提高边缘稳定性,需要SDK v6.2.0支持","uid":"0a176380-b33e-11e9-8e6a-35012f229fc1.bundle","size":3872.85,"name":"hez_ztt_fu.bundle"},"icon":{"remark":"v1.0","uid":"167f72e0-e173-11e8-b908-51298abcbcf5.png","size":61.83,"name":"hez_ztt_fu.png","url":"http://tools-manage.oss-cn-hangzhou.aliyuncs.com/167f72e0-e173-11e8-b908-51298abcbcf5.png?OSSAccessKeyId=LTAIZvD3ylHAD1vH&Expires=1616057194&Signature=4aesuhXnenASOXCQwl0logppBM4%3D"}},"platform":"mobile","tag":"中级道具"}]
|
||||
*/
|
||||
|
||||
private int count;
|
||||
private ArrayList<DocsBean> docs;
|
||||
private boolean isOnline; //手动设置
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public ArrayList<DocsBean> getDocs() {
|
||||
return docs;
|
||||
}
|
||||
|
||||
public void setDocs(ArrayList<DocsBean> docs) {
|
||||
this.docs = docs;
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
return isOnline;
|
||||
}
|
||||
|
||||
public void setOnline(boolean online) {
|
||||
isOnline = online;
|
||||
}
|
||||
|
||||
public static class DocsBean extends BaseBean {
|
||||
/**
|
||||
* _id : 6051a0aa6d670000230030c7
|
||||
* index : 1
|
||||
* tool : {"_id":"5f6ae24e570100009e006547","bundle":{"remark":"优化背景分割,提高边缘稳定性,需要SDK v6.2.0支持","uid":"0a176380-b33e-11e9-8e6a-35012f229fc1.bundle","size":3872.85,"name":"hez_ztt_fu.bundle"},"icon":{"remark":"v1.0","uid":"167f72e0-e173-11e8-b908-51298abcbcf5.png","size":61.83,"name":"hez_ztt_fu.png","url":"http://tools-manage.oss-cn-hangzhou.aliyuncs.com/167f72e0-e173-11e8-b908-51298abcbcf5.png?OSSAccessKeyId=LTAIZvD3ylHAD1vH&Expires=1616057194&Signature=4aesuhXnenASOXCQwl0logppBM4%3D"}}
|
||||
* platform : mobile
|
||||
* tag : 中级道具
|
||||
*/
|
||||
|
||||
private String _id;
|
||||
private int index;
|
||||
private ToolBean tool;
|
||||
private String platform;
|
||||
private String tag;
|
||||
|
||||
private String filePath; //原始下载来的文件的存储地址,手动设置
|
||||
private ArrayList<String> upZipFilePath;//解压的文件位置(绝对路径),手动设置
|
||||
private boolean isDownloading; //手动设置
|
||||
|
||||
// public Effect cast2Effect() {
|
||||
// return new Effect(tool.bundle.name, 0, filePath, 1, Effect.EFFECT_TYPE_STICKER, 0);
|
||||
// }
|
||||
|
||||
public String get_id() {
|
||||
return _id;
|
||||
}
|
||||
|
||||
public void set_id(String _id) {
|
||||
this._id = _id;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public ToolBean getTool() {
|
||||
return tool;
|
||||
}
|
||||
|
||||
public void setTool(ToolBean tool) {
|
||||
this.tool = tool;
|
||||
}
|
||||
|
||||
public String getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
public ArrayList<String> getUnZipFilePaths() {
|
||||
return upZipFilePath;
|
||||
}
|
||||
|
||||
public void setUpZipFilePaths(ArrayList paths) {
|
||||
upZipFilePath = paths;
|
||||
}
|
||||
|
||||
public boolean isDownloading() {
|
||||
return isDownloading;
|
||||
}
|
||||
|
||||
public void setDownloading(boolean downloading) {
|
||||
isDownloading = downloading;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getKey() {
|
||||
return _id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDesRes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageRes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageUrl() {
|
||||
if(tool==null||tool.getIcon()==null){
|
||||
return "";
|
||||
}
|
||||
return tool.getIcon().getUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanType() {
|
||||
return FaceParam.FACE_FINE_STICKER;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelAttributeData getModelAttributeData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class ToolBean {
|
||||
/**
|
||||
* _id : 5f6ae24e570100009e006547
|
||||
* bundle : {"remark":"优化背景分割,提高边缘稳定性,需要SDK v6.2.0支持","uid":"0a176380-b33e-11e9-8e6a-35012f229fc1.bundle","size":3872.85,"name":"hez_ztt_fu.bundle"}
|
||||
* icon : {"remark":"v1.0","uid":"167f72e0-e173-11e8-b908-51298abcbcf5.png","size":61.83,"name":"hez_ztt_fu.png","url":"http://tools-manage.oss-cn-hangzhou.aliyuncs.com/167f72e0-e173-11e8-b908-51298abcbcf5.png?OSSAccessKeyId=LTAIZvD3ylHAD1vH&Expires=1616057194&Signature=4aesuhXnenASOXCQwl0logppBM4%3D"}
|
||||
*/
|
||||
|
||||
private String _id;
|
||||
private BundleBean bundle;
|
||||
private IconBean icon;
|
||||
private String adapter;
|
||||
private String category;
|
||||
|
||||
public String get_id() {
|
||||
return _id;
|
||||
}
|
||||
|
||||
public void set_id(String _id) {
|
||||
this._id = _id;
|
||||
}
|
||||
|
||||
public BundleBean getBundle() {
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public void setBundle(BundleBean bundle) {
|
||||
this.bundle = bundle;
|
||||
}
|
||||
|
||||
public IconBean getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(IconBean icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public String getAdapter() {
|
||||
return adapter;
|
||||
}
|
||||
|
||||
public void setAdapter(String adapter) {
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public static class BundleBean {
|
||||
/**
|
||||
* remark : 优化背景分割,提高边缘稳定性,需要SDK v6.2.0支持
|
||||
* uid : 0a176380-b33e-11e9-8e6a-35012f229fc1.bundle
|
||||
* size : 3872.85
|
||||
* name : hez_ztt_fu.bundle
|
||||
*/
|
||||
|
||||
private String remark;
|
||||
private String uid;
|
||||
private double size;
|
||||
private String name;
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setUid(String uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public double getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(double size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public static class IconBean {
|
||||
/**
|
||||
* remark : v1.0
|
||||
* uid : 167f72e0-e173-11e8-b908-51298abcbcf5.png
|
||||
* size : 61.83
|
||||
* name : hez_ztt_fu.png
|
||||
* url : http://tools-manage.oss-cn-hangzhou.aliyuncs.com/167f72e0-e173-11e8-b908-51298abcbcf5.png?OSSAccessKeyId=LTAIZvD3ylHAD1vH&Expires=1616057194&Signature=4aesuhXnenASOXCQwl0logppBM4%3D
|
||||
*/
|
||||
|
||||
private String remark;
|
||||
private String uid;
|
||||
private double size;
|
||||
private String name;
|
||||
private String url;
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setUid(String uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public double getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(double size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.yunbao.faceunity.entity.net;
|
||||
|
||||
/**
|
||||
* Created on 2021/3/31 0031 16:12.
|
||||
* Author: xloger
|
||||
* Email:phoenix@xloger.com
|
||||
*/
|
||||
public class FineStickerTagEntity {
|
||||
private String tag;
|
||||
|
||||
public FineStickerTagEntity(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FineStickerTagEntity{" +
|
||||
"tag='" + tag + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.yunbao.faceunity.infe
|
||||
|
||||
import com.yunbao.faceunity.entity.AnimationFilterBean
|
||||
import com.yunbao.faceunity.entity.AnimojiBean
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:
|
||||
* Created on 2020/12/24
|
||||
*
|
||||
*/
|
||||
abstract class AbstractAnimojiDataFactory {
|
||||
|
||||
/* 当前选中动漫贴图下标 */
|
||||
abstract var currentAnimojiIndex: Int
|
||||
|
||||
/* 动漫贴图队列 */
|
||||
abstract val animojis: ArrayList<AnimojiBean>
|
||||
|
||||
/* 当前选中滤镜下标 */
|
||||
abstract var currentFilterIndex: Int
|
||||
|
||||
/* 滤镜队列 */
|
||||
abstract val filters: ArrayList<AnimationFilterBean>
|
||||
|
||||
abstract fun onAnimojiSelected(data: AnimojiBean)
|
||||
|
||||
abstract fun onFilterSelected(data: AnimationFilterBean)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.yunbao.faceunity.infe
|
||||
|
||||
import com.yunbao.faceunity.entity.AvatarBean
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:
|
||||
* Created on 2021/1/6
|
||||
*
|
||||
*/
|
||||
abstract class AbstractAvatarDataFactory {
|
||||
|
||||
/**
|
||||
* 人物队列
|
||||
*/
|
||||
abstract val members: ArrayList<AvatarBean>
|
||||
|
||||
/**
|
||||
* 默认选中人物下标
|
||||
*/
|
||||
abstract var currentMemberIndex: Int
|
||||
|
||||
/**
|
||||
* true 全身、 false 半身 驱动切换
|
||||
*/
|
||||
abstract var isHumanTrackSceneFull: Boolean
|
||||
|
||||
/**
|
||||
* 当前人物选中
|
||||
* @param bean AvatarBean
|
||||
*/
|
||||
abstract fun onMemberSelected(bean:AvatarBean)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.yunbao.faceunity.infe
|
||||
|
||||
|
||||
import com.yunbao.faceunity.entity.BgSegGreenBackgroundBean
|
||||
import com.yunbao.faceunity.entity.BgSegGreenBean
|
||||
import com.yunbao.faceunity.entity.BgSegGreenSafeAreaBean
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:
|
||||
* Created on 2020/12/29
|
||||
*
|
||||
*/
|
||||
abstract class AbstractBgSegGreenDataFactory {
|
||||
|
||||
/* 绿幕抠像项目数据扩展模型 */
|
||||
abstract val modelAttributeRange: HashMap<String, ModelAttributeData>
|
||||
|
||||
/* 绿幕抠像功能列表 */
|
||||
abstract val bgSegGreenActions: ArrayList<BgSegGreenBean>
|
||||
|
||||
/* 绿幕抠图安全区域功能列表*/
|
||||
abstract val bgSegGreenSafeAreas: ArrayList<BgSegGreenSafeAreaBean>
|
||||
|
||||
/* 安全区域下标 */
|
||||
abstract var bgSafeAreaIndex: Int
|
||||
|
||||
/* 刷新安全区域UI */
|
||||
abstract fun updateSafeAreaBeansAndIndex() :Boolean
|
||||
|
||||
/* 绿幕抠像背景列表 */
|
||||
abstract val bgSegGreenBackgrounds: ArrayList<BgSegGreenBackgroundBean>
|
||||
|
||||
/* 绿幕抠像当前背景下标 */
|
||||
abstract var backgroundIndex: Int
|
||||
|
||||
|
||||
/**
|
||||
* 背景图片变更
|
||||
* @param data BgSegGreenBackgroundBean
|
||||
*/
|
||||
abstract fun onBackgroundSelected(data: BgSegGreenBackgroundBean)
|
||||
|
||||
/**
|
||||
* 自定义安全区域
|
||||
*/
|
||||
abstract fun onSafeAreaAdd()
|
||||
|
||||
/**
|
||||
* 安全区域变更
|
||||
* @param data BgSegGreenSafeAreaBean
|
||||
*/
|
||||
abstract fun onSafeAreaSelected(data: BgSegGreenSafeAreaBean?)
|
||||
|
||||
/**
|
||||
* 是否开启安全区域总开关
|
||||
*/
|
||||
abstract fun isUseTemplate():Boolean
|
||||
|
||||
/**
|
||||
* 取色锚点颜色变更
|
||||
* @param array DoubleArray
|
||||
*/
|
||||
abstract fun onColorRGBChanged(array: DoubleArray)
|
||||
|
||||
/**
|
||||
* 绿幕开关
|
||||
* @param enable Boolean
|
||||
*/
|
||||
abstract fun onBgSegGreenEnableChanged(enable: Boolean)
|
||||
|
||||
|
||||
/**
|
||||
* 根据名称标识获取对应的值
|
||||
* @param key String 标识
|
||||
* @return Double 值
|
||||
*/
|
||||
abstract fun getParamIntensity(key: String): Double
|
||||
|
||||
/**
|
||||
* 根据名称标识更新对应的值
|
||||
* @param key String 标识
|
||||
* @return Double 值
|
||||
*/
|
||||
abstract fun updateParamIntensity(key: String, value: Double)
|
||||
|
||||
/**
|
||||
* 是否调用取色器功能
|
||||
*
|
||||
* @param selected
|
||||
* @param color
|
||||
*/
|
||||
abstract fun onColorPickerStateChanged(selected: Boolean, color: Int)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.yunbao.faceunity.infe;
|
||||
|
||||
|
||||
import com.yunbao.faceunity.entity.BodyBeautyBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* DESC:数据构造工厂抽象类
|
||||
* Created on 2021/4/26
|
||||
*/
|
||||
public abstract class AbstractBodyBeautyDataFactory {
|
||||
|
||||
|
||||
/**
|
||||
* 获取美体参数集合
|
||||
* @return
|
||||
*/
|
||||
public abstract ArrayList<BodyBeautyBean> getBodyBeautyParam();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取美体项目数据扩展模型
|
||||
* @return
|
||||
*/
|
||||
public abstract HashMap<String, ModelAttributeData> getModelAttributeRange();
|
||||
|
||||
|
||||
/**
|
||||
* 根据名称标识获取对应的值
|
||||
*
|
||||
* @param key String 标识
|
||||
* @return Double 值
|
||||
*/
|
||||
public abstract double getParamIntensity(String key);
|
||||
|
||||
/**
|
||||
* 根据名称标识更新对应的值
|
||||
*
|
||||
* @param key String 标识
|
||||
* @return Double 值
|
||||
*/
|
||||
public abstract void updateParamIntensity(String key, double value);
|
||||
|
||||
/**
|
||||
* 美体开关
|
||||
*
|
||||
* @param enable Boolean
|
||||
*/
|
||||
public abstract void enableBodyBeauty(boolean enable);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.yunbao.faceunity.infe
|
||||
|
||||
|
||||
import com.yunbao.faceunity.entity.FaceBeautyBean
|
||||
import com.yunbao.faceunity.entity.FaceBeautyFilterBean
|
||||
import com.yunbao.faceunity.entity.FaceBeautyStyleBean
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:数据构造工厂接口类
|
||||
* Created on 2020/12/23
|
||||
*
|
||||
*/
|
||||
abstract class AbstractFaceBeautyDataFactory {
|
||||
|
||||
/*美肤底部菜单数据*/
|
||||
abstract val skinBeauty: ArrayList<FaceBeautyBean>
|
||||
|
||||
/*美型底部菜单数据*/
|
||||
abstract val shapeBeauty: ArrayList<FaceBeautyBean>
|
||||
|
||||
/*美型脸型子项数据*/
|
||||
abstract val shapeBeautySubItem: ArrayList<FaceBeautyBean>
|
||||
|
||||
/* 滤镜底部菜单数据*/
|
||||
abstract val beautyFilters: ArrayList<FaceBeautyFilterBean>
|
||||
|
||||
/* 风格底部菜单数据*/
|
||||
abstract val beautyStyles: ArrayList<FaceBeautyStyleBean>
|
||||
|
||||
/*系统推荐配置滤镜对应下标*/
|
||||
abstract var currentFilterIndex: Int
|
||||
|
||||
/* 美颜项目数据扩展模型 */
|
||||
abstract val modelAttributeRange: HashMap<String, ModelAttributeData>
|
||||
|
||||
/*系统风格对应下标*/
|
||||
abstract var currentStyleIndex: Int
|
||||
|
||||
/**
|
||||
* 切换滤镜
|
||||
* @param name String
|
||||
* @param intensity Double
|
||||
*/
|
||||
abstract fun onFilterSelected(name: String, intensity: Double, resDes: Int)
|
||||
|
||||
/**
|
||||
* 切换风格
|
||||
* @param name String
|
||||
*/
|
||||
abstract fun onStyleSelected(name: String?)
|
||||
|
||||
/**
|
||||
* 更改滤镜强度
|
||||
* @param intensity Double
|
||||
*/
|
||||
abstract fun updateFilterIntensity(intensity: Double)
|
||||
|
||||
/**
|
||||
* 美颜开关
|
||||
* @param enable Boolean
|
||||
*/
|
||||
abstract fun enableFaceBeauty(enable: Boolean)
|
||||
|
||||
/**
|
||||
* 获取单项强度
|
||||
* @param key String
|
||||
* @return Double
|
||||
*/
|
||||
abstract fun getParamIntensity(key: String): Double
|
||||
|
||||
/**
|
||||
* 获取one hot的脸型
|
||||
*/
|
||||
abstract fun getCurrentOneHotFaceShape(): String
|
||||
|
||||
/**
|
||||
* 设置当前one hot的脸型
|
||||
*/
|
||||
abstract fun setCurrentOneHotFaceShape(faceShape:String)
|
||||
|
||||
/**
|
||||
* 设置当前脸型的UI值
|
||||
*/
|
||||
abstract fun setCurrentFaceShapeUIValue(hashMap:HashMap<String,Double>)
|
||||
|
||||
/**
|
||||
* 获取当前脸型的UI值
|
||||
*/
|
||||
abstract fun getCurrentFaceShapeUIValue() :HashMap<String,Double>
|
||||
|
||||
/**
|
||||
* 设置单项强度
|
||||
* @param key String
|
||||
* @param value Double
|
||||
*/
|
||||
abstract fun updateParamIntensity(key: String, value: Double)
|
||||
|
||||
/**
|
||||
* 将所有效果置空 -> 变成标准值
|
||||
*/
|
||||
abstract fun resetParamIntensity()
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.yunbao.faceunity.infe
|
||||
|
||||
|
||||
import com.yunbao.faceunity.entity.net.FineStickerEntity
|
||||
import com.yunbao.faceunity.entity.net.FineStickerTagEntity
|
||||
|
||||
/**
|
||||
* Created on 2021/3/31 0031 15:27.
|
||||
* Author: xloger
|
||||
* Email:phoenix@xloger.com
|
||||
*/
|
||||
abstract class AbstractFineStickerDataFactory {
|
||||
/*切换道具*/
|
||||
abstract fun onItemSelected(bean: FineStickerEntity.DocsBean?)
|
||||
/*获取标签列表*/
|
||||
abstract fun loadTagList(): List<FineStickerTagEntity>
|
||||
/*获取道具列表*/
|
||||
abstract fun loadStickerList(tag: FineStickerTagEntity): FineStickerEntity?
|
||||
/*下载道具*/
|
||||
abstract fun downloadSticker(docsBean: FineStickerEntity.DocsBean)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.yunbao.faceunity.infe;
|
||||
|
||||
import com.yunbao.faceunity.entity.LightMakeupBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class AbstractLightMakeupDataFactory {
|
||||
private int currentLightMakeupIndex;
|
||||
private ArrayList<LightMakeupBean> lightMakeUpBeans;
|
||||
public abstract void onLightMakeupSelected(LightMakeupBean data);
|
||||
public abstract void onLightMakeupIntensityChanged(double intensity);
|
||||
|
||||
public int getCurrentLightMakeupIndex() {
|
||||
return currentLightMakeupIndex;
|
||||
}
|
||||
|
||||
public void setCurrentLightMakeupIndex(int currentLightMakeupIndex) {
|
||||
this.currentLightMakeupIndex = currentLightMakeupIndex;
|
||||
}
|
||||
|
||||
public ArrayList<LightMakeupBean> getLightMakeUpBeans() {
|
||||
return lightMakeUpBeans;
|
||||
}
|
||||
|
||||
public void setLightMakeUpBeans(ArrayList<LightMakeupBean> lightMakeUpBeans) {
|
||||
this.lightMakeUpBeans = lightMakeUpBeans;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.yunbao.faceunity.infe
|
||||
|
||||
|
||||
import com.yunbao.faceunity.entity.MakeupCombinationBean
|
||||
import com.yunbao.faceunity.entity.MakeupCustomBean
|
||||
import com.yunbao.faceunity.entity.MakeupCustomClassBean
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:
|
||||
* Created on 2020/12/22
|
||||
*
|
||||
*/
|
||||
abstract class AbstractMakeupDataFactory {
|
||||
|
||||
/* 默认组合妆容下标 */
|
||||
abstract var currentCombinationIndex: Int
|
||||
|
||||
/* 美妆组合妆容配置 */
|
||||
abstract val makeupCombinations: ArrayList<MakeupCombinationBean>
|
||||
|
||||
/**
|
||||
* 组合妆容选中
|
||||
* @param bean MakeupCombinationBean
|
||||
*/
|
||||
abstract fun onMakeupCombinationSelected(bean: MakeupCombinationBean)
|
||||
|
||||
/**
|
||||
* 设置美妆整体强度
|
||||
* @param intensity Double
|
||||
*/
|
||||
abstract fun updateCombinationIntensity(intensity: Double)
|
||||
|
||||
/**
|
||||
* 进入自定义美妆
|
||||
*/
|
||||
abstract fun enterCustomMakeup()
|
||||
|
||||
/**
|
||||
* 设置美妆单项强度
|
||||
* @param key String 单项key
|
||||
* @param current Int 单项下标
|
||||
* @param intensity Double
|
||||
*/
|
||||
abstract fun updateCustomItemIntensity(key: String, current: Int, intensity: Double)
|
||||
|
||||
/**
|
||||
* 更换类别单项
|
||||
* @param key String
|
||||
* @param index Int
|
||||
*/
|
||||
abstract fun onCustomBeanSelected(key: String, index: Int)
|
||||
|
||||
/**
|
||||
* 设置单项颜色
|
||||
* @param key String
|
||||
* @param index Int
|
||||
*/
|
||||
abstract fun updateCustomColor(key: String, index: Int)
|
||||
|
||||
|
||||
/* 美妆功能菜单 */
|
||||
abstract val makeupCustomItemParams: LinkedHashMap<String, ArrayList<MakeupCustomBean>>
|
||||
|
||||
/* 美妆子项类别 */
|
||||
|
||||
abstract val makeupCustomClass: ArrayList<MakeupCustomClassBean>
|
||||
|
||||
|
||||
/**
|
||||
* 获取美妆单项当前下标
|
||||
* @param key String
|
||||
* @return Int
|
||||
*/
|
||||
abstract fun getCurrentCustomItemIndex(key: String): Int
|
||||
|
||||
/**
|
||||
* 获取美妆当前选中项颜色下标
|
||||
* @param key String
|
||||
* @param current Int
|
||||
* @return Int
|
||||
*/
|
||||
abstract fun getCurrentCustomColorIndex(key: String, current: Int): Int
|
||||
|
||||
/**
|
||||
* 获取美妆当前选中项强度
|
||||
* @param key String
|
||||
* @param current Int
|
||||
* @return Double
|
||||
*/
|
||||
abstract fun getCurrentCustomIntensity(key: String, current: Int): Double
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.yunbao.faceunity.infe
|
||||
|
||||
import com.yunbao.faceunity.entity.PropCustomBean
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:贴图道具
|
||||
* Created on 2020/12/23
|
||||
*
|
||||
*/
|
||||
abstract class AbstractPropCustomDataFactory {
|
||||
|
||||
/**
|
||||
* 默认选中道具下标
|
||||
*/
|
||||
abstract var currentPropIndex: Int
|
||||
|
||||
|
||||
/**
|
||||
* 道具队列
|
||||
*/
|
||||
abstract val propCustomBeans: ArrayList<PropCustomBean>
|
||||
|
||||
|
||||
/**
|
||||
* 道具选中
|
||||
* @param bean StickerBean
|
||||
*/
|
||||
abstract fun onItemSelected(bean: PropCustomBean)
|
||||
|
||||
|
||||
/**
|
||||
* 道具选中
|
||||
*/
|
||||
abstract fun onAddPropCustomBeanClick()
|
||||
|
||||
|
||||
companion object {
|
||||
const val TYPE_NONE = -1
|
||||
const val TYPE_ADD = -99
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.yunbao.faceunity.infe
|
||||
|
||||
import com.yunbao.faceunity.entity.PropBean
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* DESC:贴图道具
|
||||
* Created on 2020/12/23
|
||||
*
|
||||
*/
|
||||
abstract class AbstractPropDataFactory {
|
||||
|
||||
/**
|
||||
* 默认选中道具下标
|
||||
*/
|
||||
abstract var currentPropIndex: Int
|
||||
|
||||
|
||||
/**
|
||||
* 道具队列
|
||||
*/
|
||||
abstract val propBeans: ArrayList<PropBean>
|
||||
|
||||
|
||||
/**
|
||||
* 道具选中
|
||||
* @param bean StickerBean
|
||||
*/
|
||||
abstract fun onItemSelected(bean: PropBean)
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.yunbao.faceunity.listener;
|
||||
|
||||
import com.faceunity.core.enumeration.FUAIProcessorEnum;
|
||||
|
||||
/**
|
||||
* DESC:FURenderer状态回调监听
|
||||
* Created on 2021/4/29
|
||||
*/
|
||||
public interface FURendererListener {
|
||||
|
||||
/**
|
||||
* prepare完成回调
|
||||
*/
|
||||
void onPrepare();
|
||||
|
||||
/**
|
||||
* 识别到的人脸或人体数量发生变化
|
||||
*
|
||||
* @param type 类型
|
||||
* @param status 数量
|
||||
*/
|
||||
void onTrackStatusChanged(FUAIProcessorEnum type, int status);
|
||||
|
||||
|
||||
/**
|
||||
* 统计每 10 帧的平均数据,FPS 和渲染函数调用时间
|
||||
*
|
||||
* @param fps FPS
|
||||
* @param callTime 渲染函数调用时间
|
||||
*/
|
||||
void onFpsChanged(double fps, double callTime);
|
||||
|
||||
|
||||
/**
|
||||
* release完成回调
|
||||
*/
|
||||
void onRelease();
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.yunbao.faceunity.listener;
|
||||
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
/**
|
||||
* 模块配置
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class IFaceModel<T> {
|
||||
public abstract T Builder();
|
||||
|
||||
public void apply() {
|
||||
FUAIKit.getInstance().loadAIProcessor(FaceUnityConfig.BUNDLE_AI_FACE, FUAITypeEnum.FUAITYPE_FACEPROCESSOR);
|
||||
FUAIKit.getInstance().faceProcessorSetFaceLandmarkQuality(FaceUnityConfig.DEVICE_LEVEL);
|
||||
}
|
||||
public abstract void setEnable(boolean enable);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.yunbao.faceunity.repo;
|
||||
|
||||
import com.faceunity.core.model.animationFilter.AnimationFilterTypeEnum;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.AnimationFilterBean;
|
||||
import com.yunbao.faceunity.entity.AnimojiBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DESC:Animoji数据构造
|
||||
* Created on 2021/3/25
|
||||
*/
|
||||
public class AnimojiSource {
|
||||
|
||||
|
||||
/**
|
||||
* 构造贴图数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<AnimojiBean> buildAnimojis() {
|
||||
ArrayList<AnimojiBean> array = new ArrayList<>();
|
||||
array.add(new AnimojiBean(R.mipmap.icon_control_delete_all, null));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_cartoon_princess, "animoji/cartoon_princess_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_qgirl, "animoji/qgirl_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_kaola, "animoji/kaola_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_wuxia, "animoji/wuxia_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_baihu, "animoji/baihu_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_frog_st, "animoji/frog_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_huangya, "animoji/huangya_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_hetun, "animoji/hetun_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_douniuquan, "animoji/douniuquan_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_hashiqi, "animoji/hashiqi_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_baimao, "animoji/baimao_Animoji.bundle"));
|
||||
array.add(new AnimojiBean(R.mipmap.icon_animoji_kuloutou, "animoji/kuloutou_Animoji.bundle"));
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造滤镜数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<AnimationFilterBean> buildFilters() {
|
||||
ArrayList<AnimationFilterBean> filters = new ArrayList<>();
|
||||
filters.add(new AnimationFilterBean(R.mipmap.icon_control_delete_all, AnimationFilterTypeEnum.Origin));
|
||||
filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_anime, AnimationFilterTypeEnum.Comic));
|
||||
filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_portrait_dynamiceffect, AnimationFilterTypeEnum.Portrait));
|
||||
filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_sketch, AnimationFilterTypeEnum.Sketch));
|
||||
filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_oilpainting, AnimationFilterTypeEnum.Oil));
|
||||
filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_sandlpainting, AnimationFilterTypeEnum.Sand));
|
||||
filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_penpainting, AnimationFilterTypeEnum.Pen));
|
||||
filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_pencilpainting, AnimationFilterTypeEnum.Pencil));
|
||||
filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_graffiti, AnimationFilterTypeEnum.Granffiti));
|
||||
return filters;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.yunbao.faceunity.repo;
|
||||
|
||||
import com.faceunity.core.avatar.avatar.Color;
|
||||
import com.faceunity.core.avatar.avatar.TransForm;
|
||||
import com.faceunity.core.avatar.model.Avatar;
|
||||
import com.faceunity.core.avatar.model.Scene;
|
||||
import com.faceunity.core.entity.FUAnimationData;
|
||||
import com.faceunity.core.entity.FUAvatarAnimFilterParams;
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.entity.FUColorRGBData;
|
||||
import com.faceunity.core.entity.FUCoordinate3DData;
|
||||
import com.faceunity.core.entity.FUTranslationScale;
|
||||
import com.faceunity.core.entity.FUVisibleBundleData;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.AvatarBean;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DESC:Avatar数据构造
|
||||
* Created on 2021/3/30
|
||||
*/
|
||||
public class AvatarSource {
|
||||
// Avatar
|
||||
private static String BUNDLE_AVATAR_CONTROLLER = "graphics" + File.separator + "controller_cpp.bundle";
|
||||
private static String BUNDLE_AVATAR_CONFIG = "pta" + File.separator + "controller_config.bundle";
|
||||
private static String BUNDLE_AVATAR_BACKGROUND = "pta" + File.separator + "default_bg.bundle";
|
||||
|
||||
public static String BOY = "boy";
|
||||
public static String GIRL = "girl";
|
||||
|
||||
/**
|
||||
* 构造成员列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<AvatarBean> buildMembers() {
|
||||
ArrayList<AvatarBean> avatarBeans = new ArrayList<>();
|
||||
avatarBeans.add(new AvatarBean(R.mipmap.icon_avatar_female, GIRL));
|
||||
avatarBeans.add(new AvatarBean(R.mipmap.icon_avatar_male, BOY));
|
||||
return avatarBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造场景
|
||||
*
|
||||
* @param avatar
|
||||
* @return
|
||||
*/
|
||||
public static Scene buildSceneModel(Avatar avatar) {
|
||||
FUBundleData controlBundle = new FUBundleData(BUNDLE_AVATAR_CONTROLLER);
|
||||
FUBundleData avatarConfig = new FUBundleData(BUNDLE_AVATAR_CONFIG);
|
||||
Scene sceneModel = new Scene(controlBundle, avatarConfig);
|
||||
sceneModel.addAvatar(avatar);
|
||||
sceneModel.processorConfig.setEnableHumanProcessor(true);
|
||||
return sceneModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取男孩对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Avatar buildBoyData(boolean isFull) {
|
||||
String ptaBoyDir = "pta/boy/";
|
||||
ArrayList<FUBundleData> components = new ArrayList();
|
||||
components.add(new FUBundleData(ptaBoyDir + "head.bundle"));
|
||||
components.add(new FUBundleData(ptaBoyDir + "midBody_male.bundle"));
|
||||
components.add(new FUBundleData(ptaBoyDir + "male_hair_5.bundle"));
|
||||
components.add(new FUBundleData(ptaBoyDir + "toushi_7.bundle"));
|
||||
components.add(new FUBundleData(ptaBoyDir + "peishi_erding_2.bundle"));
|
||||
components.add(new FUBundleData(ptaBoyDir + "waitao_3.bundle"));
|
||||
components.add(new FUBundleData(ptaBoyDir + "kuzi_changku_5.bundle"));
|
||||
components.add(new FUBundleData(ptaBoyDir + "xiezi_tuoxie_2.bundle"));
|
||||
int[] invisibleList = {2,3,4};
|
||||
components.add(new FUVisibleBundleData("",invisibleList,""));
|
||||
ArrayList<FUAnimationData> animations = buildAnimations();
|
||||
Avatar model = new Avatar(components);
|
||||
for (FUAnimationData animationData:animations){
|
||||
model.animation.addAnimation(animationData);
|
||||
}
|
||||
model.color.setColor(Color.Skin,new FUColorRGBData(227.0,158.0,132.0));
|
||||
TransForm avatarTransForm = model.transForm;
|
||||
avatarTransForm.setInstanceEnableHumanAnimDriver(true);
|
||||
avatarTransForm.setPosition(isFull ? new FUCoordinate3DData(0.0, 58.14, -618.94) : new FUCoordinate3DData(0.0, 11.76, -183.89));
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取女孩对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Avatar buildGirlData(boolean isFull) {
|
||||
String ptaGirlDir = "pta/girl/";
|
||||
ArrayList<FUBundleData> components = new ArrayList();
|
||||
components.add(new FUBundleData(ptaGirlDir + "head.bundle"));
|
||||
components.add(new FUBundleData(ptaGirlDir + "midBody_female.bundle"));
|
||||
components.add(new FUBundleData(ptaGirlDir + "female_hair_23.bundle"));
|
||||
components.add(new FUBundleData(ptaGirlDir + "toushi_5.bundle"));
|
||||
components.add(new FUBundleData(ptaGirlDir + "taozhuang_12.bundle"));
|
||||
components.add(new FUBundleData(ptaGirlDir + "facemakeup_3.bundle"));
|
||||
components.add(new FUBundleData(ptaGirlDir + "xiezi_danxie.bundle"));
|
||||
int[] invisibleList = {2,3,4};
|
||||
components.add(new FUVisibleBundleData("",invisibleList,""));
|
||||
ArrayList<FUAnimationData> animations = buildAnimations();
|
||||
Avatar model = new Avatar(components );
|
||||
for (FUAnimationData animationData:animations){
|
||||
model.animation.addAnimation(animationData);
|
||||
}
|
||||
model.color.setColor(Color.Skin,new FUColorRGBData(255.0,202.0,186.0));
|
||||
TransForm avatarTransForm = model.transForm;
|
||||
avatarTransForm.setInstanceEnableHumanAnimDriver(true);
|
||||
avatarTransForm.setPosition(isFull ? new FUCoordinate3DData(0.0, 58.14, -618.94) : new FUCoordinate3DData(0.0, 11.76, -183.89));
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 外部传入组件和动画构建
|
||||
*
|
||||
* @param strComponents 组件bundle
|
||||
* @param strAnimations 动画bundle
|
||||
* @return
|
||||
*/
|
||||
public static Avatar buildAvatarData(ArrayList<String> strComponents, ArrayList<String> strAnimations) {
|
||||
ArrayList<FUBundleData> components = new ArrayList();
|
||||
for (String component : strComponents) {
|
||||
components.add(new FUBundleData(component));
|
||||
}
|
||||
|
||||
Avatar model = new Avatar(components);
|
||||
for (String animation : strAnimations) {
|
||||
model.animation.addAnimation(new FUAnimationData(new FUBundleData(animation)));
|
||||
}
|
||||
//位置等avatar基本参数构建
|
||||
TransForm avatarTransForm = model.transForm;
|
||||
avatarTransForm.setPosition(new FUCoordinate3DData(20, 45, -618.94));
|
||||
avatarTransForm.setTranslationScale(new FUTranslationScale(0.0f,0.0f,0.0f));
|
||||
avatarTransForm.setInstanceEnableHumanAnimDriver(true);
|
||||
model.animation.setHumanProcessorSetAvatarAnimFilterParams(new FUAvatarAnimFilterParams(8, 0.09f, 0.120f));
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造动画参数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<FUAnimationData> buildAnimations() {
|
||||
String animDir = "pta/gesture/";
|
||||
ArrayList<FUAnimationData> animations = new ArrayList();
|
||||
animations.add(new FUAnimationData(new FUBundleData(animDir + "anim_idle.bundle")));
|
||||
return animations;
|
||||
}
|
||||
|
||||
public static void setSceneBackGround(Scene sceneModel, boolean hasBackGround) {
|
||||
sceneModel.setBackgroundBundle(hasBackGround ? new FUBundleData(BUNDLE_AVATAR_BACKGROUND) : null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.yunbao.faceunity.repo;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
|
||||
import com.faceunity.core.controller.bgSegGreen.BgSegGreenParam;
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.model.bgSegGreen.BgSegGreen;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.BgSegGreenBackgroundBean;
|
||||
import com.yunbao.faceunity.entity.BgSegGreenBean;
|
||||
import com.yunbao.faceunity.entity.BgSegGreenSafeAreaBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
import com.yunbao.faceunity.utils.FaceUnityData;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* DESC:绿幕抠像数据构造
|
||||
* Created on 2021/3/25
|
||||
*/
|
||||
public class BgSegGreenSource {
|
||||
private static final String GREEN_SAFE_AREA_CUSTOM = "green_safe_area_custom";
|
||||
|
||||
private static double SIMILARITY = 0.5;//相似度
|
||||
private static double SMOOTHNESS = 0.3;//平滑度
|
||||
private static double TRANSPARENCY = 0.67;//透明度
|
||||
|
||||
/**
|
||||
* 构造绿幕抠像对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static BgSegGreen buildBgSegGreen() {
|
||||
BgSegGreen bgSegGreen = new BgSegGreen(new FUBundleData(FaceUnityConfig.BUNDLE_BG_SEG_GREEN));
|
||||
bgSegGreen.setSimilarity(BgSegGreenSource.SIMILARITY);
|
||||
bgSegGreen.setSmoothness(BgSegGreenSource.SMOOTHNESS);
|
||||
bgSegGreen.setTransparency(BgSegGreenSource.TRANSPARENCY);
|
||||
return bgSegGreen;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型属性扩展数据
|
||||
*
|
||||
* @return HashMap<String, ModelAttributeData>
|
||||
*/
|
||||
public static HashMap<String, ModelAttributeData> buildModelAttributeRange() {
|
||||
HashMap<String, ModelAttributeData> params = new HashMap<String, ModelAttributeData>();
|
||||
params.put(BgSegGreenParam.SIMILARITY, new ModelAttributeData(SIMILARITY, 0.0, 0.0, 1.0));
|
||||
params.put(BgSegGreenParam.SMOOTHNESS, new ModelAttributeData(SMOOTHNESS, 0.0, 0.0, 1.0));
|
||||
params.put(BgSegGreenParam.TRANSPARENCY, new ModelAttributeData(TRANSPARENCY, 0.0, 0.0, 1.0));
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绿幕抠像功能列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<BgSegGreenBean> buildBgSegGreenAction() {
|
||||
ArrayList<BgSegGreenBean> actions = new ArrayList<BgSegGreenBean>();
|
||||
actions.add(new BgSegGreenBean(BgSegGreenParam.RGB_COLOR, R.string.bg_seg_green_key_color, R.drawable.icon_green_color_selector, R.drawable.icon_green_color_selector, BgSegGreenBean.ButtonType.NORMAL2_BUTTON));
|
||||
actions.add(new BgSegGreenBean(BgSegGreenParam.SIMILARITY, R.string.bg_seg_green_similarity, R.drawable.icon_green_similarityr_close_selector, R.drawable.icon_green_similarityr_open_selector, BgSegGreenBean.ButtonType.NORMAL1_BUTTON));
|
||||
actions.add(new BgSegGreenBean(BgSegGreenParam.SMOOTHNESS, R.string.bg_seg_green_smooth, R.drawable.icon_green_smooth_close_selector, R.drawable.icon_green_similarityr_open_selector, BgSegGreenBean.ButtonType.NORMAL1_BUTTON));
|
||||
actions.add(new BgSegGreenBean(BgSegGreenParam.TRANSPARENCY, R.string.bg_seg_green_alpha, R.drawable.icon_green_transparency_close_selector, R.drawable.icon_green_transparency_open_selector, BgSegGreenBean.ButtonType.NORMAL1_BUTTON));
|
||||
actions.add(new BgSegGreenBean("", R.string.bg_seg_green_safe_area, R.drawable.icon_green_safe_area_close_selector, R.drawable.icon_green_safe_area_open_selector, BgSegGreenBean.ButtonType.SWITCH_BUTTON));
|
||||
return actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绿幕抠像安全区域功能列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<BgSegGreenSafeAreaBean> buildBgSegGreenSafeArea() {
|
||||
String fileDir = "bg_seg_green" + File.separator + "sample" + File.separator;
|
||||
ArrayList<BgSegGreenSafeAreaBean> safeAreaBeans = new ArrayList<BgSegGreenSafeAreaBean>();
|
||||
safeAreaBeans.add(new BgSegGreenSafeAreaBean(R.mipmap.icon_control_return, BgSegGreenSafeAreaBean.ButtonType.BACK_BUTTON));//返回
|
||||
safeAreaBeans.add(new BgSegGreenSafeAreaBean(R.mipmap.icon_control_none, BgSegGreenSafeAreaBean.ButtonType.NONE_BUTTON));//不选
|
||||
safeAreaBeans.add(new BgSegGreenSafeAreaBean(R.mipmap.icon_control_square_add, BgSegGreenSafeAreaBean.ButtonType.NORMAL2_BUTTON));//自定义
|
||||
BgSegGreenSafeAreaBean customerBean = buildSafeAreaCustomBean(getCachePortraitSegment());
|
||||
if (customerBean != null) {
|
||||
safeAreaBeans.add(customerBean);
|
||||
}
|
||||
safeAreaBeans.add(new BgSegGreenSafeAreaBean(R.mipmap.icon_green_safe_area1, BgSegGreenSafeAreaBean.ButtonType.NORMAL1_BUTTON,fileDir + "safe_area1.jpg"));//区域一
|
||||
safeAreaBeans.add(new BgSegGreenSafeAreaBean(R.mipmap.icon_green_safe_area2, BgSegGreenSafeAreaBean.ButtonType.NORMAL1_BUTTON,fileDir + "safe_area2.jpg"));//区域二
|
||||
return safeAreaBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造自定义安全区域图片
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
public static BgSegGreenSafeAreaBean buildSafeAreaCustomBean(String path) {
|
||||
if (path != null && path.trim().length() > 0 && new File(path).exists()) {
|
||||
saveCachePortraitSegment(path);
|
||||
return new BgSegGreenSafeAreaBean(0, BgSegGreenSafeAreaBean.ButtonType.NORMAL1_BUTTON, path,false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绿幕抠像背景列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<BgSegGreenBackgroundBean> buildBgSegGreenBackground() {
|
||||
ArrayList<BgSegGreenBackgroundBean> backgroundBeans = new ArrayList<>();
|
||||
String fileDir = "bg_seg_green" + File.separator + "sample" + File.separator;
|
||||
backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.cancel, R.mipmap.icon_control_none, null));
|
||||
backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.bg_seg_green_science, R.mipmap.icon_green_science, fileDir + "science.mp4"));
|
||||
backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.bg_seg_green_beach, R.mipmap.icon_green_bg_beach, fileDir + "beach.mp4"));
|
||||
backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.bg_seg_green_classroom, R.mipmap.icon_green_bg_classroom, fileDir + "classroom.mp4"));
|
||||
backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.bg_seg_green_ink, R.mipmap.icon_green_ink_painting, fileDir + "ink_painting.mp4"));
|
||||
backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.bg_seg_green_forest, R.mipmap.icon_green_bg_forest, fileDir + "forest.mp4"));
|
||||
return backgroundBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存自定义安全区域图片
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
public static void saveCachePortraitSegment(String path) {
|
||||
SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(GREEN_SAFE_AREA_CUSTOM, MODE_PRIVATE);
|
||||
sp.edit().putString(GREEN_SAFE_AREA_CUSTOM, path).apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自定义安全区域图片
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getCachePortraitSegment() {
|
||||
SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(GREEN_SAFE_AREA_CUSTOM, MODE_PRIVATE);
|
||||
return sp.getString(GREEN_SAFE_AREA_CUSTOM, "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.yunbao.faceunity.repo;
|
||||
|
||||
import com.faceunity.core.controller.bodyBeauty.BodyBeautyParam;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.BodyBeautyBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* DESC:美体数据构造
|
||||
* Created on 2021/3/26
|
||||
*/
|
||||
public class BodyBeautySource {
|
||||
|
||||
public static final String BUNDLE_BODY_BEAUTY = "graphics" + File.separator + "body_slim.bundle";
|
||||
|
||||
|
||||
/**
|
||||
* 构造美体
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<BodyBeautyBean> buildBodyBeauty() {
|
||||
ArrayList<BodyBeautyBean> params = new ArrayList<>();
|
||||
params.add(new BodyBeautyBean(BodyBeautyParam.BODY_SLIM_INTENSITY, R.string.slimming, R.drawable.icon_body_slimming_close_selector, R.drawable.icon_body_slimming_open_selector));
|
||||
params.add(new BodyBeautyBean(BodyBeautyParam.LEG_STRETCH_INTENSITY, R.string.long_legs, R.drawable.icon_body_stovepipe_close_selector, R.drawable.icon_body_stovepipe_open_selector));
|
||||
params.add(new BodyBeautyBean(BodyBeautyParam.WAIST_SLIM_INTENSITY, R.string.thin_waist, R.drawable.icon_body_waist_close_selector, R.drawable.icon_body_waist_open_selector));
|
||||
params.add(new BodyBeautyBean(BodyBeautyParam.SHOULDER_SLIM_INTENSITY, R.string.beautify_shoulder, R.drawable.icon_body_shoulder_close_selector, R.drawable.icon_body_shoulder_open_selector));
|
||||
params.add(new BodyBeautyBean(BodyBeautyParam.HIP_SLIM_INTENSITY, R.string.beautify_hip_slim, R.drawable.icon_body_hip_close_selector, R.drawable.icon_body_hip_open_selector));
|
||||
params.add(new BodyBeautyBean(BodyBeautyParam.HEAD_SLIM_INTENSITY, R.string.beautify_head_slim, R.drawable.icon_body_little_head_close_selector, R.drawable.icon_body_little_head_open_selector));
|
||||
params.add(new BodyBeautyBean(BodyBeautyParam.LEG_SLIM_INTENSITY, R.string.beautify_leg_thin_slim, R.drawable.icon_body_thin_leg_close_selector, R.drawable.icon_body_thin_leg_open_selector));
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型属性扩展数据
|
||||
*
|
||||
* @return HashMap<String, ModelAttributeData>
|
||||
*/
|
||||
public static HashMap<String, ModelAttributeData> buildModelAttributeRange() {
|
||||
HashMap<String, ModelAttributeData> params = new HashMap<>();
|
||||
params.put(BodyBeautyParam.BODY_SLIM_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(BodyBeautyParam.LEG_STRETCH_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(BodyBeautyParam.WAIST_SLIM_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(BodyBeautyParam.SHOULDER_SLIM_INTENSITY, new ModelAttributeData(0.5, 0.5, 0.0, 1.0));
|
||||
params.put(BodyBeautyParam.HIP_SLIM_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(BodyBeautyParam.HEAD_SLIM_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(BodyBeautyParam.LEG_SLIM_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
return params;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,761 @@
|
||||
package com.yunbao.faceunity.repo;
|
||||
|
||||
|
||||
import com.faceunity.core.controller.facebeauty.FaceBeautyParam;
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.enumeration.FUFaceBeautyMultiModePropertyEnum;
|
||||
import com.faceunity.core.enumeration.FUFaceBeautyPropertyModeEnum;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.facebeauty.FaceBeauty;
|
||||
import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.data.FaceBeautyData;
|
||||
import com.yunbao.faceunity.data.FaceBeautyDataFactory;
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyBean;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyFilterBean;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyStyleBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.utils.FUUtils;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
import com.yunbao.faceunity.utils.FuDeviceUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* DESC:美颜数据构造
|
||||
* Created on 2021/3/27
|
||||
*/
|
||||
public class FaceBeautySource {
|
||||
|
||||
private static ArrayList<FaceBeautyFilterBean> filters = new ArrayList<>();
|
||||
private static FaceBeautyData faceBeautyData;
|
||||
|
||||
/**
|
||||
* 获取默认推荐美颜模型
|
||||
* 一个app生命周期请求一次
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static FaceBeauty getDefaultFaceBeauty() {
|
||||
FaceBeauty recommendFaceBeauty = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION));
|
||||
if (FaceUnityConfig.OPEN_FACE_BEAUTY_TO_FILE)
|
||||
faceBeautyData = FUUtils.loadFaceBeautyData();
|
||||
if (faceBeautyData != null) {
|
||||
//有本地缓存
|
||||
FaceBeautyDataFactory.setDiskCurrentStyleIndex(faceBeautyData.styleTypeIndex);
|
||||
FUUtils.setFaceBeauty(faceBeautyData, recommendFaceBeauty);
|
||||
} else {
|
||||
//没有本地缓存
|
||||
recommendFaceBeauty.setFilterName(FaceBeautyFilterEnum.ZIRAN_2);
|
||||
recommendFaceBeauty.setFilterIntensity(0.4);
|
||||
/*美肤*/
|
||||
recommendFaceBeauty.setSharpenIntensity(0.2);
|
||||
recommendFaceBeauty.setColorIntensity(0.3);
|
||||
recommendFaceBeauty.setRedIntensity(0.3);
|
||||
recommendFaceBeauty.setBlurIntensity(4.2);
|
||||
/*美型*/
|
||||
recommendFaceBeauty.setFaceShapeIntensity(1.0);
|
||||
recommendFaceBeauty.setEyeEnlargingIntensity(0.4);
|
||||
recommendFaceBeauty.setCheekVIntensity(0.5);
|
||||
recommendFaceBeauty.setNoseIntensity(0.5);
|
||||
recommendFaceBeauty.setForHeadIntensity(0.3);
|
||||
recommendFaceBeauty.setMouthIntensity(0.4);
|
||||
recommendFaceBeauty.setChinIntensity(0.3);
|
||||
//性能最优策略
|
||||
if (FaceUnityConfig.DEVICE_LEVEL > FuDeviceUtils.DEVICE_LEVEL_MID) {
|
||||
setFaceBeautyPropertyMode(recommendFaceBeauty);
|
||||
}
|
||||
}
|
||||
|
||||
return recommendFaceBeauty;
|
||||
}
|
||||
|
||||
/**
|
||||
* 高端机的时候,开启4个相对吃性能的模式
|
||||
* 1.祛黑眼圈 MODE2
|
||||
* 2.祛法令纹 MODE2
|
||||
* 3.大眼 MODE3
|
||||
* 4.嘴型 MODE3
|
||||
*/
|
||||
private static void setFaceBeautyPropertyMode(FaceBeauty faceBeauty) {
|
||||
/*
|
||||
* 多模式属性
|
||||
* 属性名称|支持模式|默认模式|最早支持版本
|
||||
* 美白 colorIntensity|MODE1 MODE2|MODE2|MODE2 8.2.0;
|
||||
* 祛黑眼圈 removePouchIntensity|MODE1 MODE2|MODE2|MODE2 8.2.0;
|
||||
* 祛法令纹 removeLawPatternIntensity|MODE1 MODE1|MODE2|MODE2 8.2.0;
|
||||
* 窄脸程度 cheekNarrowIntensity|MODE1 MODE2|MODE2|MODE2 8.0.0;
|
||||
* 小脸程度 cheekSmallIntensity|MODE1 MODE2|MODE2|MODE2 8.0.0;
|
||||
* 大眼程度 eyeEnlargingIntensity|MODE1 MODE2 MODE3|MODE3|MODE2 8.0.0;MODE3 8.2.0;
|
||||
* 额头调整程度 forHeadIntensity|MODE1 MODE2|MODE2|MODE2 8.0.0;
|
||||
* 瘦鼻程度 noseIntensity|MODE1 MODE2|MODE2|MODE2 8.0.0;
|
||||
* 嘴巴调整程度 mouthIntensity|MODE1 MODE2 MODE3|MODE3|MODE2 8.0.0;MODE3 8.2.0;
|
||||
*/
|
||||
faceBeauty.addPropertyMode(FUFaceBeautyMultiModePropertyEnum.REMOVE_POUCH_INTENSITY, FUFaceBeautyPropertyModeEnum.MODE2);
|
||||
faceBeauty.addPropertyMode(FUFaceBeautyMultiModePropertyEnum.REMOVE_NASOLABIAL_FOLDS_INTENSITY, FUFaceBeautyPropertyModeEnum.MODE2);
|
||||
faceBeauty.addPropertyMode(FUFaceBeautyMultiModePropertyEnum.EYE_ENLARGING_INTENSITY, FUFaceBeautyPropertyModeEnum.MODE3);
|
||||
faceBeauty.addPropertyMode(FUFaceBeautyMultiModePropertyEnum.MOUTH_INTENSITY, FUFaceBeautyPropertyModeEnum.MODE3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化美肤参数
|
||||
*
|
||||
* @return ArrayList<FaceBeautyBean>
|
||||
*/
|
||||
public static ArrayList<FaceBeautyBean> buildSkinParams() {
|
||||
ArrayList<FaceBeautyBean> params = new ArrayList<>();
|
||||
params.add(new FaceBeautyBean(
|
||||
FaceBeautyParam.BLUR_INTENSITY
|
||||
, R.string.beauty_box_heavy_blur_fine
|
||||
, R.drawable.icon_beauty_skin_buffing_close_selector
|
||||
, R.drawable.icon_beauty_skin_buffing_open_selector
|
||||
, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SKIN
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.COLOR_INTENSITY, R.string.beauty_box_color_level,
|
||||
R.drawable.icon_beauty_skin_color_close_selector, R.drawable.icon_beauty_skin_color_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SKIN
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.RED_INTENSITY, R.string.beauty_box_red_level,
|
||||
R.drawable.icon_beauty_skin_red_close_selector, R.drawable.icon_beauty_skin_red_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SKIN
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.SHARPEN_INTENSITY, R.string.beauty_box_sharpen,
|
||||
R.drawable.icon_beauty_skin_sharpen_close_selector, R.drawable.icon_beauty_skin_sharpen_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SKIN
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.EYE_BRIGHT_INTENSITY, R.string.beauty_box_eye_bright,
|
||||
R.drawable.icon_beauty_skin_eyes_bright_close_selector, R.drawable.icon_beauty_skin_eyes_bright_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SKIN
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.TOOTH_WHITEN_INTENSITY, R.string.beauty_box_tooth_whiten,
|
||||
R.drawable.icon_beauty_skin_teeth_close_selector, R.drawable.icon_beauty_skin_teeth_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SKIN
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.REMOVE_POUCH_INTENSITY, R.string.beauty_micro_pouch,
|
||||
R.drawable.icon_beauty_skin_dark_circles_close_selector, R.drawable.icon_beauty_skin_dark_circles_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SKIN)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.REMOVE_NASOLABIAL_FOLDS_INTENSITY, R.string.beauty_micro_nasolabial,
|
||||
R.drawable.icon_beauty_skin_wrinkle_close_selector, R.drawable.icon_beauty_skin_wrinkle_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SKIN)
|
||||
);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化美型参数
|
||||
*
|
||||
* @return ArrayList<FaceBeautyBean>
|
||||
*/
|
||||
public static ArrayList<FaceBeautyBean> buildShapeParams() {
|
||||
ArrayList<FaceBeautyBean> params = new ArrayList<>();
|
||||
// params.add(
|
||||
// new FaceBeautyBean(
|
||||
// "", R.string.avatar_face_face,
|
||||
// R.drawable.icon_beauty_shape_face_shape_close_selector, R.drawable.icon_beauty_shape_face_shape_open_selector, FaceBeautyBean.ButtonType.SUB_ITEM_BUTTON
|
||||
// )
|
||||
// );
|
||||
|
||||
//瘦脸
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.CHEEK_THINNING_INTENSITY, R.string.beauty_box_cheek_thinning,
|
||||
R.drawable.icon_beauty_shape_face_cheekthin_close_selector, R.drawable.icon_beauty_shape_face_cheekthin_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
|
||||
//V脸
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.CHEEK_V_INTENSITY, R.string.beauty_box_cheek_v,
|
||||
R.drawable.icon_beauty_shape_face_v_close_selector, R.drawable.icon_beauty_shape_face_v_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
|
||||
//窄脸
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.CHEEK_NARROW_INTENSITY, R.string.beauty_box_cheek_narrow,
|
||||
R.drawable.icon_beauty_shape_face_narrow_close_selector, R.drawable.icon_beauty_shape_face_narrow_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
|
||||
//小脸 -> 短脸 --使用的参数是以前小脸的
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.CHEEK_SHORT_INTENSITY, R.string.beauty_box_cheek_short,
|
||||
R.drawable.icon_beauty_shape_face_short_close_selector, R.drawable.icon_beauty_shape_face_short_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
|
||||
//小脸 -> 新增
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.CHEEK_SMALL_INTENSITY, R.string.beauty_box_cheek_small,
|
||||
R.drawable.icon_beauty_shape_face_little_close_selector, R.drawable.icon_beauty_shape_face_little_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.INTENSITY_CHEEKBONES_INTENSITY, R.string.beauty_box_cheekbones,
|
||||
R.drawable.icon_beauty_shape_cheek_bones_close_selector, R.drawable.icon_beauty_shape_cheek_bones_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.INTENSITY_LOW_JAW_INTENSITY, R.string.beauty_box_lower_jaw,
|
||||
R.drawable.icon_beauty_shape_lower_jaw_close_selector, R.drawable.icon_beauty_shape_lower_jaw_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.EYE_ENLARGING_INTENSITY, R.string.beauty_box_eye_enlarge,
|
||||
R.drawable.icon_beauty_shape_enlarge_eye_close_selector, R.drawable.icon_beauty_shape_enlarge_eye_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.EYE_CIRCLE_INTENSITY, R.string.beauty_box_eye_circle,
|
||||
R.drawable.icon_beauty_shape_round_eye_close_selector, R.drawable.icon_beauty_shape_round_eye_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.CHIN_INTENSITY, R.string.beauty_box_intensity_chin,
|
||||
R.drawable.icon_beauty_shape_chin_close_selector, R.drawable.icon_beauty_shape_chin_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.FOREHEAD_INTENSITY, R.string.beauty_box_intensity_forehead,
|
||||
R.drawable.icon_beauty_shape_forehead_close_selector, R.drawable.icon_beauty_shape_forehead_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.NOSE_INTENSITY, R.string.beauty_box_intensity_nose,
|
||||
R.drawable.icon_beauty_shape_thin_nose_close_selector, R.drawable.icon_beauty_shape_thin_nose_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.MOUTH_INTENSITY, R.string.beauty_box_intensity_mouth,
|
||||
R.drawable.icon_beauty_shape_mouth_close_selector, R.drawable.icon_beauty_shape_mouth_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.CANTHUS_INTENSITY, R.string.beauty_micro_canthus,
|
||||
R.drawable.icon_beauty_shape_open_eyes_close_selector, R.drawable.icon_beauty_shape_open_eyes_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.EYE_SPACE_INTENSITY, R.string.beauty_micro_eye_space,
|
||||
R.drawable.icon_beauty_shape_distance_close_selector, R.drawable.icon_beauty_shape_distance_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.EYE_ROTATE_INTENSITY, R.string.beauty_micro_eye_rotate,
|
||||
R.drawable.icon_beauty_shape_angle_close_selector, R.drawable.icon_beauty_shape_angle_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.LONG_NOSE_INTENSITY, R.string.beauty_micro_long_nose,
|
||||
R.drawable.icon_beauty_shape_proboscis_close_selector, R.drawable.icon_beauty_shape_proboscis_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.PHILTRUM_INTENSITY, R.string.beauty_micro_philtrum,
|
||||
R.drawable.icon_beauty_shape_shrinking_close_selector, R.drawable.icon_beauty_shape_shrinking_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.SMILE_INTENSITY, R.string.beauty_micro_smile,
|
||||
R.drawable.icon_beauty_shape_smile_close_selector, R.drawable.icon_beauty_shape_smile_open_selector, 0
|
||||
, true,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.BROW_HEIGHT_INTENSITY,
|
||||
R.string.beauty_brow_height,
|
||||
R.drawable.icon_beauty_shape_brow_height_close_selector,
|
||||
R.drawable.icon_beauty_shape_brow_height_open_selector,
|
||||
R.string.brow_height_tips,
|
||||
FaceUnityConfig.DEVICE_LEVEL > FuDeviceUtils.DEVICE_LEVEL_MID,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
|
||||
)
|
||||
);
|
||||
params.add(
|
||||
new FaceBeautyBean(
|
||||
FaceBeautyParam.BROW_SPACE_INTENSITY, R.string.beauty_brow_space,
|
||||
R.drawable.icon_beauty_shape_brow_space_close_selector, R.drawable.icon_beauty_shape_brow_space_open_selector,
|
||||
R.string.brow_space_tips, FaceUnityConfig.DEVICE_LEVEL > FuDeviceUtils.DEVICE_LEVEL_MID,
|
||||
FaceParam.FACE_BEAUTY_SHAPE
|
||||
)
|
||||
);
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载脸型子项
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<FaceBeautyBean> buildFaceShapeSubItemParams() {
|
||||
return buildSubItemParams(FaceBeautyParam.FACE_SHAPE);
|
||||
}
|
||||
|
||||
public static ArrayList<FaceBeautyBean> buildSubItemParams(String key) {
|
||||
ArrayList<FaceBeautyBean> params = new ArrayList<>();
|
||||
// if (key != null && !key.isEmpty()) {
|
||||
// if (key.equals(FaceBeautyParam.FACE_SHAPE)) {
|
||||
// //返回
|
||||
// params.add(
|
||||
// new FaceBeautyBean(
|
||||
// "", R.string.back,
|
||||
// R.mipmap.icon_beauty_back, R.mipmap.icon_beauty_back, FaceBeautyBean.ButtonType.BACK_BUTTON
|
||||
// )
|
||||
// );
|
||||
//
|
||||
// //自然 V脸 -> 自然脸
|
||||
// params.add(
|
||||
// new FaceBeautyBean(
|
||||
// FaceBeautyParam.CHEEK_V_INTENSITY, R.string.beauty_box_cheek_natural,
|
||||
// R.drawable.icon_beauty_shape_face_natural_close_selector, R.drawable.icon_beauty_shape_face_natural_open_selector
|
||||
// )
|
||||
// );
|
||||
//
|
||||
// //女神 瘦脸 -> 女神脸
|
||||
// params.add(
|
||||
// new FaceBeautyBean(
|
||||
// FaceBeautyParam.CHEEK_THINNING_INTENSITY, R.string.beauty_box_cheek_goddess,
|
||||
// R.drawable.icon_beauty_shape_face_goddess_close_selector, R.drawable.icon_beauty_shape_face_goddess_open_selector
|
||||
// )
|
||||
// );
|
||||
//
|
||||
// //长脸
|
||||
// params.add(
|
||||
// new FaceBeautyBean(
|
||||
// FaceBeautyParam.CHEEK_LONG_INTENSITY, R.string.beauty_box_cheek_long_face,
|
||||
// R.drawable.icon_beauty_shape_face_long_close_selector, R.drawable.icon_beauty_shape_face_long_open_selector
|
||||
// )
|
||||
// );
|
||||
//
|
||||
// //圆脸
|
||||
// params.add(
|
||||
// new FaceBeautyBean(
|
||||
// FaceBeautyParam.CHEEK_CIRCLE_INTENSITY, R.string.beauty_box_cheek_round_face,
|
||||
// R.drawable.icon_beauty_shape_face_round_close_selector, R.drawable.icon_beauty_shape_face_round_open_selector
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化参数扩展列表
|
||||
*
|
||||
* @return HashMap<String, ModelAttributeData>
|
||||
*/
|
||||
public static HashMap<String, ModelAttributeData> buildModelAttributeRange() {
|
||||
HashMap<String, ModelAttributeData> params = new HashMap<>();
|
||||
/*美肤*/
|
||||
params.put(FaceBeautyParam.COLOR_INTENSITY, new ModelAttributeData(0.3, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.BLUR_INTENSITY, new ModelAttributeData(4.2, 0.0, 0.0, 6.0));
|
||||
params.put(FaceBeautyParam.RED_INTENSITY, new ModelAttributeData(0.3, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.SHARPEN_INTENSITY, new ModelAttributeData(0.2, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.EYE_BRIGHT_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.TOOTH_WHITEN_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.REMOVE_POUCH_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.REMOVE_NASOLABIAL_FOLDS_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
/*美型*/
|
||||
params.put(FaceBeautyParam.FACE_SHAPE_INTENSITY, new ModelAttributeData(1.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.CHEEK_THINNING_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.CHEEK_LONG_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.CHEEK_CIRCLE_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.CHEEK_V_INTENSITY, new ModelAttributeData(0.5, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.CHEEK_NARROW_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.CHEEK_SHORT_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.CHEEK_SMALL_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.INTENSITY_CHEEKBONES_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.INTENSITY_LOW_JAW_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.EYE_ENLARGING_INTENSITY, new ModelAttributeData(0.4, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.EYE_CIRCLE_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.CHIN_INTENSITY, new ModelAttributeData(0.3, 0.5, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.FOREHEAD_INTENSITY, new ModelAttributeData(0.3, 0.5, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.NOSE_INTENSITY, new ModelAttributeData(0.5, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.MOUTH_INTENSITY, new ModelAttributeData(0.4, 0.5, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.CANTHUS_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.EYE_SPACE_INTENSITY, new ModelAttributeData(0.5, 0.5, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.EYE_ROTATE_INTENSITY, new ModelAttributeData(0.5, 0.5, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.LONG_NOSE_INTENSITY, new ModelAttributeData(0.5, 0.5, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.PHILTRUM_INTENSITY, new ModelAttributeData(0.5, 0.5, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.SMILE_INTENSITY, new ModelAttributeData(0.0, 0.0, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.BROW_HEIGHT_INTENSITY, new ModelAttributeData(0.5, 0.5, 0.0, 1.0));
|
||||
params.put(FaceBeautyParam.BROW_SPACE_INTENSITY, new ModelAttributeData(0.5, 0.5, 0.0, 1.0));
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化滤镜参数
|
||||
*
|
||||
* @return ArrayList<FaceBeautyFilterBean>
|
||||
*/
|
||||
public static ArrayList<FaceBeautyFilterBean> buildFilters() {
|
||||
if (!filters.isEmpty()) {
|
||||
return filters;
|
||||
}
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ORIGIN, R.mipmap.icon_beauty_filter_cancel, R.string.origin, 0.0));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_1, R.mipmap.icon_beauty_filter_natural_1, R.string.ziran_1, getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_1)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_2, R.mipmap.icon_beauty_filter_natural_2, R.string.ziran_2, getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_2)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_3, R.mipmap.icon_beauty_filter_natural_3, R.string.ziran_3, getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_3)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_4, R.mipmap.icon_beauty_filter_natural_4, R.string.ziran_4, getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_4)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_5, R.mipmap.icon_beauty_filter_natural_5, R.string.ziran_5, getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_5)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_6, R.mipmap.icon_beauty_filter_natural_6, R.string.ziran_6, getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_6)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_7, R.mipmap.icon_beauty_filter_natural_7, R.string.ziran_7, getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_7)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_8, R.mipmap.icon_beauty_filter_natural_8, R.string.ziran_8, getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_8)));
|
||||
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_1, R.mipmap.icon_beauty_filter_texture_gray_1, R.string.zhiganhui_1, getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_1)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_2, R.mipmap.icon_beauty_filter_texture_gray_2, R.string.zhiganhui_2, getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_2)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_3, R.mipmap.icon_beauty_filter_texture_gray_3, R.string.zhiganhui_3, getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_3)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_4, R.mipmap.icon_beauty_filter_texture_gray_4, R.string.zhiganhui_4, getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_4)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_5, R.mipmap.icon_beauty_filter_texture_gray_5, R.string.zhiganhui_5, getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_5)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_6, R.mipmap.icon_beauty_filter_texture_gray_6, R.string.zhiganhui_6, getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_6)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_7, R.mipmap.icon_beauty_filter_texture_gray_7, R.string.zhiganhui_7, getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_7)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_8, R.mipmap.icon_beauty_filter_texture_gray_8, R.string.zhiganhui_8, getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_8)));
|
||||
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_1, R.mipmap.icon_beauty_filter_peach_1, R.string.mitao_1, getDiskFilterValue(FaceBeautyFilterEnum.MITAO_1)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_2, R.mipmap.icon_beauty_filter_peach_2, R.string.mitao_2, getDiskFilterValue(FaceBeautyFilterEnum.MITAO_2)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_3, R.mipmap.icon_beauty_filter_peach_3, R.string.mitao_3, getDiskFilterValue(FaceBeautyFilterEnum.MITAO_3)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_4, R.mipmap.icon_beauty_filter_peach_4, R.string.mitao_4, getDiskFilterValue(FaceBeautyFilterEnum.MITAO_4)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_5, R.mipmap.icon_beauty_filter_peach_5, R.string.mitao_5, getDiskFilterValue(FaceBeautyFilterEnum.MITAO_5)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_6, R.mipmap.icon_beauty_filter_peach_6, R.string.mitao_6, getDiskFilterValue(FaceBeautyFilterEnum.MITAO_6)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_7, R.mipmap.icon_beauty_filter_peach_7, R.string.mitao_7, getDiskFilterValue(FaceBeautyFilterEnum.MITAO_7)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_8, R.mipmap.icon_beauty_filter_peach_8, R.string.mitao_8, getDiskFilterValue(FaceBeautyFilterEnum.MITAO_8)));
|
||||
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_1, R.mipmap.icon_beauty_filter_bailiang_1, R.string.bailiang_1, getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_1)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_2, R.mipmap.icon_beauty_filter_bailiang_2, R.string.bailiang_2, getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_2)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_3, R.mipmap.icon_beauty_filter_bailiang_3, R.string.bailiang_3, getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_3)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_4, R.mipmap.icon_beauty_filter_bailiang_4, R.string.bailiang_4, getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_4)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_5, R.mipmap.icon_beauty_filter_bailiang_5, R.string.bailiang_5, getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_5)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_6, R.mipmap.icon_beauty_filter_bailiang_6, R.string.bailiang_6, getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_6)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_7, R.mipmap.icon_beauty_filter_bailiang_7, R.string.bailiang_7, getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_7)));
|
||||
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_1, R.mipmap.icon_beauty_filter_fennen_1, R.string.fennen_1, getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_1)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_2, R.mipmap.icon_beauty_filter_fennen_2, R.string.fennen_2, getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_2)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_3, R.mipmap.icon_beauty_filter_fennen_3, R.string.fennen_3, getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_3)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_5, R.mipmap.icon_beauty_filter_fennen_5, R.string.fennen_5, getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_5)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_6, R.mipmap.icon_beauty_filter_fennen_6, R.string.fennen_6, getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_6)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_7, R.mipmap.icon_beauty_filter_fennen_7, R.string.fennen_7, getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_7)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_8, R.mipmap.icon_beauty_filter_fennen_8, R.string.fennen_8, getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_8)));
|
||||
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_1, R.mipmap.icon_beauty_filter_lengsediao_1, R.string.lengsediao_1, getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_1)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_2, R.mipmap.icon_beauty_filter_lengsediao_2, R.string.lengsediao_2, getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_2)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_3, R.mipmap.icon_beauty_filter_lengsediao_3, R.string.lengsediao_3, getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_3)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_4, R.mipmap.icon_beauty_filter_lengsediao_4, R.string.lengsediao_4, getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_4)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_7, R.mipmap.icon_beauty_filter_lengsediao_7, R.string.lengsediao_7, getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_7)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_8, R.mipmap.icon_beauty_filter_lengsediao_8, R.string.lengsediao_8, getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_8)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_11, R.mipmap.icon_beauty_filter_lengsediao_11, R.string.lengsediao_11, getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_11)));
|
||||
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.NUANSEDIAO_1, R.mipmap.icon_beauty_filter_nuansediao_1, R.string.nuansediao_1, getDiskFilterValue(FaceBeautyFilterEnum.NUANSEDIAO_1)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.NUANSEDIAO_2, R.mipmap.icon_beauty_filter_nuansediao_2, R.string.nuansediao_2, getDiskFilterValue(FaceBeautyFilterEnum.NUANSEDIAO_2)));
|
||||
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_1, R.mipmap.icon_beauty_filter_gexing_1, R.string.gexing_1, getDiskFilterValue(FaceBeautyFilterEnum.GEXING_1)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_2, R.mipmap.icon_beauty_filter_gexing_2, R.string.gexing_2, getDiskFilterValue(FaceBeautyFilterEnum.GEXING_2)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_3, R.mipmap.icon_beauty_filter_gexing_3, R.string.gexing_3, getDiskFilterValue(FaceBeautyFilterEnum.GEXING_3)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_4, R.mipmap.icon_beauty_filter_gexing_4, R.string.gexing_4, getDiskFilterValue(FaceBeautyFilterEnum.GEXING_4)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_5, R.mipmap.icon_beauty_filter_gexing_5, R.string.gexing_5, getDiskFilterValue(FaceBeautyFilterEnum.GEXING_5)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_7, R.mipmap.icon_beauty_filter_gexing_7, R.string.gexing_7, getDiskFilterValue(FaceBeautyFilterEnum.GEXING_7)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_10, R.mipmap.icon_beauty_filter_gexing_10, R.string.gexing_10, getDiskFilterValue(FaceBeautyFilterEnum.GEXING_10)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_11, R.mipmap.icon_beauty_filter_gexing_11, R.string.gexing_11, getDiskFilterValue(FaceBeautyFilterEnum.GEXING_11)));
|
||||
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.XIAOQINGXIN_1, R.mipmap.icon_beauty_filter_xiaoqingxin_1, R.string.xiaoqingxin_1, getDiskFilterValue(FaceBeautyFilterEnum.XIAOQINGXIN_1)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.XIAOQINGXIN_3, R.mipmap.icon_beauty_filter_xiaoqingxin_3, R.string.xiaoqingxin_3, getDiskFilterValue(FaceBeautyFilterEnum.XIAOQINGXIN_3)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.XIAOQINGXIN_4, R.mipmap.icon_beauty_filter_xiaoqingxin_4, R.string.xiaoqingxin_4, getDiskFilterValue(FaceBeautyFilterEnum.XIAOQINGXIN_4)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.XIAOQINGXIN_6, R.mipmap.icon_beauty_filter_xiaoqingxin_6, R.string.xiaoqingxin_6, getDiskFilterValue(FaceBeautyFilterEnum.XIAOQINGXIN_6)));
|
||||
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.HEIBAI_1, R.mipmap.icon_beauty_filter_heibai_1, R.string.heibai_1, getDiskFilterValue(FaceBeautyFilterEnum.HEIBAI_1)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.HEIBAI_2, R.mipmap.icon_beauty_filter_heibai_2, R.string.heibai_2, getDiskFilterValue(FaceBeautyFilterEnum.HEIBAI_2)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.HEIBAI_3, R.mipmap.icon_beauty_filter_heibai_3, R.string.heibai_3, getDiskFilterValue(FaceBeautyFilterEnum.HEIBAI_3)));
|
||||
filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.HEIBAI_4, R.mipmap.icon_beauty_filter_heibai_4, R.string.heibai_4, getDiskFilterValue(FaceBeautyFilterEnum.HEIBAI_4)));
|
||||
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从磁盘获取所有项滤镜强度
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
private static double getDiskFilterValue(String key) {
|
||||
if (faceBeautyData != null) {
|
||||
return faceBeautyData.filterMap.get(key);
|
||||
} else {
|
||||
return 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String CONFIG_BIAOZHUN = "biaozhun";
|
||||
private static final String CONFIG_HUAJIAO = "huajiao";
|
||||
private static final String CONFIG_KUAISHOU = "kuaishou";
|
||||
private static final String CONFIG_QINGYAN = "qingyan";
|
||||
private static final String CONFIG_SHANGTANG = "shangtang";
|
||||
private static final String CONFIG_YINGKE = "yingke";
|
||||
private static final String CONFIG_ZIJIETIAODONG = "zijietiaodong";
|
||||
|
||||
|
||||
/**
|
||||
* 初始化风格推荐
|
||||
*
|
||||
* @return ArrayList<FaceBeautyBean>
|
||||
*/
|
||||
public static ArrayList<FaceBeautyStyleBean> buildStylesParams() {
|
||||
ArrayList<FaceBeautyStyleBean> params = new ArrayList<>();
|
||||
params.add(new FaceBeautyStyleBean(CONFIG_KUAISHOU, R.drawable.icon_beauty_style_1_selector, R.string.beauty_face_style_1,FaceParam.FACE_BEAUTY_STYLE));
|
||||
params.add(new FaceBeautyStyleBean(CONFIG_QINGYAN, R.drawable.icon_beauty_style_2_selector, R.string.beauty_face_style_2,FaceParam.FACE_BEAUTY_STYLE));
|
||||
params.add(new FaceBeautyStyleBean(CONFIG_ZIJIETIAODONG, R.drawable.icon_beauty_style_3_selector, R.string.beauty_face_style_3,FaceParam.FACE_BEAUTY_STYLE));
|
||||
params.add(new FaceBeautyStyleBean(CONFIG_HUAJIAO, R.drawable.icon_beauty_style_4_selector, R.string.beauty_face_style_4,FaceParam.FACE_BEAUTY_STYLE));
|
||||
params.add(new FaceBeautyStyleBean(CONFIG_YINGKE, R.drawable.icon_beauty_style_5_selector, R.string.beauty_face_style_5,FaceParam.FACE_BEAUTY_STYLE));
|
||||
params.add(new FaceBeautyStyleBean(CONFIG_SHANGTANG, R.drawable.icon_beauty_style_6_selector, R.string.beauty_face_style_6,FaceParam.FACE_BEAUTY_STYLE));
|
||||
params.add(new FaceBeautyStyleBean(CONFIG_BIAOZHUN, R.drawable.icon_beauty_style_7_selector, R.string.beauty_face_style_7,FaceParam.FACE_BEAUTY_STYLE));
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 风格对应参数配置
|
||||
*/
|
||||
public static HashMap<String, Runnable> styleParams = new HashMap<String, Runnable>() {
|
||||
{
|
||||
put(CONFIG_KUAISHOU, () -> {
|
||||
FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION));
|
||||
model.setFaceShapeIntensity(1.0);
|
||||
model.setColorIntensity(0.5);
|
||||
model.setBlurIntensity(3.6);
|
||||
model.setEyeBrightIntensity(0.35);
|
||||
model.setToothIntensity(0.25);
|
||||
model.setCheekThinningIntensity(0.45);
|
||||
model.setCheekVIntensity(0.08);
|
||||
model.setCheekSmallIntensity(0.05);
|
||||
model.setEyeEnlargingIntensity(0.3);
|
||||
FaceBeautyDataFactory.faceBeauty = model;
|
||||
FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
|
||||
});
|
||||
put(CONFIG_QINGYAN, () -> {
|
||||
FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION));
|
||||
model.setFaceShapeIntensity(1.0);
|
||||
model.setFilterName(FaceBeautyFilterEnum.ZIRAN_3);
|
||||
model.setFilterIntensity(0.3);
|
||||
model.setColorIntensity(0.4);
|
||||
model.setRedIntensity(0.2);
|
||||
model.setBlurIntensity(3.6);
|
||||
model.setEyeBrightIntensity(0.5);
|
||||
model.setToothIntensity(0.4);
|
||||
model.setCheekThinningIntensity(0.3);
|
||||
model.setNoseIntensity(0.5);
|
||||
model.setEyeEnlargingIntensity(0.25);
|
||||
FaceBeautyDataFactory.faceBeauty = model;
|
||||
FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
});
|
||||
put(CONFIG_ZIJIETIAODONG, () -> {
|
||||
FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION));
|
||||
model.setFaceShapeIntensity(1.0);
|
||||
model.setColorIntensity(0.4);
|
||||
model.setRedIntensity(0.3);
|
||||
model.setBlurIntensity(2.4);
|
||||
model.setCheekThinningIntensity(0.3);
|
||||
model.setCheekSmallIntensity(0.15);
|
||||
model.setEyeEnlargingIntensity(0.65);
|
||||
model.setNoseIntensity(0.3);
|
||||
FaceBeautyDataFactory.faceBeauty = model;
|
||||
FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
});
|
||||
put(CONFIG_HUAJIAO, () -> {
|
||||
FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION));
|
||||
model.setFaceShapeIntensity(1.0);
|
||||
model.setColorIntensity(0.7);
|
||||
model.setBlurIntensity(3.9);
|
||||
model.setCheekThinningIntensity(0.3);
|
||||
model.setCheekSmallIntensity(0.05);
|
||||
model.setEyeEnlargingIntensity(0.65);
|
||||
FaceBeautyDataFactory.faceBeauty = model;
|
||||
FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
});
|
||||
put(CONFIG_YINGKE, () -> {
|
||||
FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION));
|
||||
model.setFaceShapeIntensity(1.0);
|
||||
model.setFilterName(FaceBeautyFilterEnum.FENNEN_2);
|
||||
model.setFilterIntensity(0.5);
|
||||
model.setColorIntensity(0.6);
|
||||
model.setBlurIntensity(3.0);
|
||||
model.setCheekThinningIntensity(0.5);
|
||||
model.setEyeEnlargingIntensity(0.65);
|
||||
FaceBeautyDataFactory.faceBeauty = model;
|
||||
FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
});
|
||||
put(CONFIG_SHANGTANG, () -> {
|
||||
FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION));
|
||||
model.setFaceShapeIntensity(1.0);
|
||||
model.setFilterName(FaceBeautyFilterEnum.FENNEN_2);
|
||||
model.setFilterIntensity(0.8);
|
||||
model.setColorIntensity(0.7);
|
||||
model.setBlurIntensity(4.2);
|
||||
model.setEyeEnlargingIntensity(0.6);
|
||||
model.setCheekThinningIntensity(0.3);
|
||||
FaceBeautyDataFactory.faceBeauty = model;
|
||||
FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
});
|
||||
put(CONFIG_BIAOZHUN, () -> {
|
||||
FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION));
|
||||
model.setFaceShapeIntensity(1.0);
|
||||
model.setFilterName(FaceBeautyFilterEnum.ZIRAN_5);
|
||||
model.setFilterIntensity(0.55);
|
||||
model.setColorIntensity(0.2);
|
||||
model.setRedIntensity(0.65);
|
||||
model.setBlurIntensity(3.3);
|
||||
model.setCheekSmallIntensity(0.05);
|
||||
model.setCheekThinningIntensity(0.1);
|
||||
FaceBeautyDataFactory.faceBeauty = model;
|
||||
FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 克隆模型
|
||||
*
|
||||
* @param faceBeauty
|
||||
* @return
|
||||
*/
|
||||
public static FaceBeauty clone(FaceBeauty faceBeauty) {
|
||||
FaceBeauty cloneFaceBeauty = new FaceBeauty(new FUBundleData(faceBeauty.getControlBundle().getPath()));
|
||||
/*滤镜*/
|
||||
cloneFaceBeauty.setFilterName(faceBeauty.getFilterName());
|
||||
cloneFaceBeauty.setFilterIntensity(faceBeauty.getFilterIntensity());
|
||||
/*美肤*/
|
||||
cloneFaceBeauty.setBlurIntensity(faceBeauty.getBlurIntensity());
|
||||
cloneFaceBeauty.setEnableHeavyBlur(faceBeauty.getEnableHeavyBlur());
|
||||
cloneFaceBeauty.setEnableSkinDetect(faceBeauty.getEnableSkinDetect());
|
||||
cloneFaceBeauty.setNonSkinBlurIntensity(faceBeauty.getNonSkinBlurIntensity());
|
||||
cloneFaceBeauty.setBlurType(faceBeauty.getBlurType());
|
||||
cloneFaceBeauty.setEnableBlurUseMask(faceBeauty.getEnableBlurUseMask());
|
||||
cloneFaceBeauty.setColorIntensity(faceBeauty.getColorIntensity());
|
||||
cloneFaceBeauty.setRedIntensity(faceBeauty.getRedIntensity());
|
||||
cloneFaceBeauty.setSharpenIntensity(faceBeauty.getSharpenIntensity());
|
||||
cloneFaceBeauty.setEyeBrightIntensity(faceBeauty.getEyeBrightIntensity());
|
||||
cloneFaceBeauty.setToothIntensity(faceBeauty.getToothIntensity());
|
||||
cloneFaceBeauty.setRemovePouchIntensity(faceBeauty.getRemovePouchIntensity());
|
||||
cloneFaceBeauty.setRemoveLawPatternIntensity(faceBeauty.getRemoveLawPatternIntensity());
|
||||
/*美型*/
|
||||
cloneFaceBeauty.setFaceShape(faceBeauty.getFaceShape());
|
||||
cloneFaceBeauty.setFaceShapeIntensity(faceBeauty.getFaceShapeIntensity());
|
||||
cloneFaceBeauty.setCheekThinningIntensity(faceBeauty.getCheekThinningIntensity());
|
||||
cloneFaceBeauty.setCheekVIntensity(faceBeauty.getCheekVIntensity());
|
||||
cloneFaceBeauty.setCheekLongIntensity(faceBeauty.getCheekLongIntensity());
|
||||
cloneFaceBeauty.setCheekCircleIntensity(faceBeauty.getCheekCircleIntensity());
|
||||
cloneFaceBeauty.setCheekNarrowIntensity(faceBeauty.getCheekNarrowIntensity());
|
||||
cloneFaceBeauty.setCheekShortIntensity(faceBeauty.getCheekShortIntensity());
|
||||
cloneFaceBeauty.setCheekSmallIntensity(faceBeauty.getCheekSmallIntensity());
|
||||
cloneFaceBeauty.setCheekBonesIntensity(faceBeauty.getCheekBonesIntensity());
|
||||
cloneFaceBeauty.setLowerJawIntensity(faceBeauty.getLowerJawIntensity());
|
||||
cloneFaceBeauty.setEyeEnlargingIntensity(faceBeauty.getEyeEnlargingIntensity());
|
||||
cloneFaceBeauty.setChinIntensity(faceBeauty.getChinIntensity());
|
||||
cloneFaceBeauty.setForHeadIntensity(faceBeauty.getForHeadIntensity());
|
||||
cloneFaceBeauty.setNoseIntensity(faceBeauty.getNoseIntensity());
|
||||
cloneFaceBeauty.setMouthIntensity(faceBeauty.getMouthIntensity());
|
||||
cloneFaceBeauty.setCanthusIntensity(faceBeauty.getCanthusIntensity());
|
||||
cloneFaceBeauty.setEyeSpaceIntensity(faceBeauty.getEyeSpaceIntensity());
|
||||
cloneFaceBeauty.setEyeRotateIntensity(faceBeauty.getEyeRotateIntensity());
|
||||
cloneFaceBeauty.setLongNoseIntensity(faceBeauty.getLongNoseIntensity());
|
||||
cloneFaceBeauty.setPhiltrumIntensity(faceBeauty.getPhiltrumIntensity());
|
||||
cloneFaceBeauty.setSmileIntensity(faceBeauty.getSmileIntensity());
|
||||
cloneFaceBeauty.setEyeCircleIntensity(faceBeauty.getEyeCircleIntensity());
|
||||
cloneFaceBeauty.setBrowHeightIntensity(faceBeauty.getBrowHeightIntensity());
|
||||
cloneFaceBeauty.setBrowSpaceIntensity(faceBeauty.getBrowSpaceIntensity());
|
||||
cloneFaceBeauty.setChangeFramesIntensity(faceBeauty.getChangeFramesIntensity());
|
||||
return cloneFaceBeauty;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
package com.yunbao.faceunity.repo;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.entity.FUColorRGBData;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum;
|
||||
import com.faceunity.core.model.littleMakeup.LightMakeup;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.LightMakeupBean;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
import com.yunbao.faceunity.utils.FaceUnityData;
|
||||
import com.yunbao.faceunity.utils.FileUtils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* DESC:轻美妆数据构造
|
||||
* Created on 2021/3/27
|
||||
*/
|
||||
public class LightMakeupSource {
|
||||
|
||||
/**
|
||||
* 构造轻美妆队列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<LightMakeupBean> buildLightMakeup() {
|
||||
ArrayList<LightMakeupBean> makeups = new ArrayList<>();
|
||||
makeups.add(new LightMakeupBean(R.string.makeup_radio_remove, R.mipmap.icon_control_none, null, 0.0, FaceBeautyFilterEnum.ZIRAN_2, 0.4));
|
||||
/*桃花*/
|
||||
makeups.add(new LightMakeupBean(R.string.makeup_peach_blossom, R.mipmap.icon_light_makeup_peachblossom, "taohua", 0.9, FaceBeautyFilterEnum.FENNEN_3, 0.9));
|
||||
/*西柚*/
|
||||
makeups.add(new LightMakeupBean(R.string.makeup_grapefruit, R.mipmap.icon_light_makeup_grapefruit, "xiyou", 1.0, FaceBeautyFilterEnum.LENGSEDIAO_4, 1.0));
|
||||
/*清透*/
|
||||
makeups.add(new LightMakeupBean(R.string.makeup_clear, R.mipmap.icon_light_makeup_clear, "qingtou", 0.9, FaceBeautyFilterEnum.XIAOQINGXIN_1, 0.9));
|
||||
/*男友*/
|
||||
makeups.add(new LightMakeupBean(R.string.makeup_boyfriend, R.mipmap.icon_light_makeup_boyfriend, "nanyou", 1.0, FaceBeautyFilterEnum.XIAOQINGXIN_3, 1.0));
|
||||
return makeups;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 风格对应参数配置
|
||||
*/
|
||||
public static HashMap<String, Runnable> LightMakeupParams = new HashMap<String, Runnable>() {
|
||||
{
|
||||
put("taohua", () -> {
|
||||
LightMakeup lightMakeup = new LightMakeup(new FUBundleData(FaceUnityConfig.BUNDLE_LIGHT_MAKEUP));
|
||||
lightMakeup.setBlusherTex(LightMakeUpEnum.MAKEUP_BLUSHER_01.path);
|
||||
lightMakeup.setBlusherIntensity(0.9);
|
||||
lightMakeup.setEyeShadowTex(LightMakeUpEnum.MAKEUP_EYE_SHADOW_01.path);
|
||||
lightMakeup.setEyeShadowIntensity(0.9);
|
||||
lightMakeup.setEyeBrowTex(LightMakeUpEnum.MAKEUP_EYEBROW_01.path);
|
||||
lightMakeup.setEyeBrowIntensity(0.5);
|
||||
lightMakeup.setLipColor(LightMakeUpEnum.MAKEUP_LIPSTICK_01.getLipColorRGBData());
|
||||
lightMakeup.setLipIntensity(0.9);
|
||||
FURenderKit.getInstance().setLightMakeup(lightMakeup);
|
||||
});
|
||||
put("xiyou", () -> {
|
||||
LightMakeup lightMakeup = new LightMakeup(new FUBundleData(FaceUnityConfig.BUNDLE_LIGHT_MAKEUP));
|
||||
lightMakeup.setBlusherTex(LightMakeUpEnum.MAKEUP_BLUSHER_23.path);
|
||||
lightMakeup.setBlusherIntensity(1.0);
|
||||
lightMakeup.setEyeShadowTex(LightMakeUpEnum.MAKEUP_EYE_SHADOW_21.path);
|
||||
lightMakeup.setEyeShadowIntensity(0.75);
|
||||
lightMakeup.setEyeBrowTex(LightMakeUpEnum.MAKEUP_EYEBROW_19.path);
|
||||
lightMakeup.setEyeBrowIntensity(0.6);
|
||||
lightMakeup.setLipColor(LightMakeUpEnum.MAKEUP_LIPSTICK_21.getLipColorRGBData());
|
||||
lightMakeup.setLipIntensity(0.8);
|
||||
FURenderKit.getInstance().setLightMakeup(lightMakeup);
|
||||
});
|
||||
put("qingtou", () -> {
|
||||
LightMakeup lightMakeup = new LightMakeup(new FUBundleData(FaceUnityConfig.BUNDLE_LIGHT_MAKEUP));
|
||||
lightMakeup.setBlusherTex(LightMakeUpEnum.MAKEUP_BLUSHER_22.path);
|
||||
lightMakeup.setBlusherIntensity(0.9);
|
||||
lightMakeup.setEyeShadowTex(LightMakeUpEnum.MAKEUP_EYE_SHADOW_20.path);
|
||||
lightMakeup.setEyeShadowIntensity(0.65);
|
||||
lightMakeup.setEyeBrowTex(LightMakeUpEnum.MAKEUP_EYEBROW_18.path);
|
||||
lightMakeup.setEyeBrowIntensity(0.45);
|
||||
lightMakeup.setLipColor(LightMakeUpEnum.MAKEUP_LIPSTICK_20.getLipColorRGBData());
|
||||
lightMakeup.setLipIntensity(0.8);
|
||||
FURenderKit.getInstance().setLightMakeup(lightMakeup);
|
||||
});
|
||||
put("nanyou", () -> {
|
||||
LightMakeup lightMakeup = new LightMakeup(new FUBundleData(FaceUnityConfig.BUNDLE_LIGHT_MAKEUP));
|
||||
lightMakeup.setBlusherTex(LightMakeUpEnum.MAKEUP_BLUSHER_20.path);
|
||||
lightMakeup.setBlusherIntensity(0.8);
|
||||
lightMakeup.setEyeShadowTex(LightMakeUpEnum.MAKEUP_EYE_SHADOW_18.path);
|
||||
lightMakeup.setEyeShadowIntensity(0.9);
|
||||
lightMakeup.setEyeBrowTex(LightMakeUpEnum.MAKEUP_EYEBROW_16.path);
|
||||
lightMakeup.setEyeBrowIntensity(0.65);
|
||||
lightMakeup.setLipColor(LightMakeUpEnum.MAKEUP_LIPSTICK_18.getLipColorRGBData());
|
||||
lightMakeup.setLipIntensity(1.0);
|
||||
FURenderKit.getInstance().setLightMakeup(lightMakeup);
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//region 轻美妆效果枚举
|
||||
public enum LightMakeUpEnum {
|
||||
/**
|
||||
* 美妆项,前几项是预置的效果
|
||||
* 排在列表最前方,顺序为桃花妆、雀斑妆、朋克妆(其中朋克没有腮红,3个妆容的眼线、眼睫毛共用1个的)
|
||||
*/
|
||||
// 腮红
|
||||
MAKEUP_BLUSHER_01("MAKEUP_BLUSHER_01", "light_makeup/blusher/mu_blush_01.png", R.mipmap.icon_light_makeup_blush_01, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_02("MAKEUP_BLUSHER_02", "light_makeup/blusher/mu_blush_02.png", R.mipmap.icon_light_makeup_blush_02, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_03("MAKEUP_BLUSHER_03", "light_makeup/blusher/mu_blush_03.png", R.mipmap.icon_light_makeup_blush_03, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_04("MAKEUP_BLUSHER_04", "light_makeup/blusher/mu_blush_04.png", R.mipmap.icon_light_makeup_blush_04, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_05("MAKEUP_BLUSHER_05", "light_makeup/blusher/mu_blush_05.png", R.mipmap.icon_light_makeup_blush_05, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_06("MAKEUP_BLUSHER_06", "light_makeup/blusher/mu_blush_06.png", R.mipmap.icon_light_makeup_blush_06, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_07("MAKEUP_BLUSHER_07", "light_makeup/blusher/mu_blush_07.png", R.mipmap.icon_light_makeup_blush_07, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_08("MAKEUP_BLUSHER_08", "light_makeup/blusher/mu_blush_08.png", R.mipmap.icon_light_makeup_blush_08, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_09("MAKEUP_BLUSHER_09", "light_makeup/blusher/mu_blush_09.png", R.mipmap.icon_light_makeup_blush_09, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_10("MAKEUP_BLUSHER_10", "light_makeup/blusher/mu_blush_10.png", R.mipmap.icon_light_makeup_blush_10, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_11("MAKEUP_BLUSHER_11", "light_makeup/blusher/mu_blush_11.png", R.mipmap.icon_light_makeup_blush_11, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_12("MAKEUP_BLUSHER_12", "light_makeup/blusher/mu_blush_12.png", R.mipmap.icon_light_makeup_blush_12, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_13("MAKEUP_BLUSHER_13", "light_makeup/blusher/mu_blush_13.png", R.mipmap.icon_light_makeup_blush_13, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_14("MAKEUP_BLUSHER_14", "light_makeup/blusher/mu_blush_14.png", R.mipmap.icon_light_makeup_blush_14, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_15("MAKEUP_BLUSHER_15", "light_makeup/blusher/mu_blush_15.png", R.mipmap.icon_light_makeup_blush_15, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_16("MAKEUP_BLUSHER_16", "light_makeup/blusher/mu_blush_16.png", R.mipmap.icon_light_makeup_blush_16, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_17("MAKEUP_BLUSHER_17", "light_makeup/blusher/mu_blush_17.png", R.mipmap.icon_light_makeup_blush_17, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_18("MAKEUP_BLUSHER_18", "light_makeup/blusher/mu_blush_18.png", R.mipmap.icon_light_makeup_blush_18, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_19("MAKEUP_BLUSHER_19", "light_makeup/blusher/mu_blush_19.png", R.mipmap.icon_light_makeup_blush_19, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_20("MAKEUP_BLUSHER_20", "light_makeup/blusher/mu_blush_20.png", R.mipmap.icon_light_makeup_blush_20, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_21("MAKEUP_BLUSHER_21", "light_makeup/blusher/mu_blush_21.png", R.mipmap.icon_light_makeup_blush_21, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_22("MAKEUP_BLUSHER_22", "light_makeup/blusher/mu_blush_22.png", R.mipmap.icon_light_makeup_blush_22, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_23("MAKEUP_BLUSHER_23", "light_makeup/blusher/mu_blush_23.png", R.mipmap.icon_light_makeup_blush_23, R.string.makeup_radio_blusher),
|
||||
|
||||
MAKEUP_BLUSHER_24("MAKEUP_BLUSHER_24", "light_makeup/blusher/mu_blush_24.png", R.mipmap.icon_light_makeup_blush_24, R.string.makeup_radio_blusher),
|
||||
|
||||
// 眉毛
|
||||
MAKEUP_EYEBROW_01("MAKEUP_EYEBROW_01", "light_makeup/eyebrow/mu_eyebrow_01.png", R.mipmap.icon_light_makeup_eyebrow_01, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_02("MAKEUP_EYEBROW_02", "light_makeup/eyebrow/mu_eyebrow_02.png", R.mipmap.icon_light_makeup_eyebrow_02, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_03("MAKEUP_EYEBROW_03", "light_makeup/eyebrow/mu_eyebrow_03.png", R.mipmap.icon_light_makeup_eyebrow_03, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_04("MAKEUP_EYEBROW_04", "light_makeup/eyebrow/mu_eyebrow_04.png", R.mipmap.icon_light_makeup_eyebrow_04, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_05("MAKEUP_EYEBROW_05", "light_makeup/eyebrow/mu_eyebrow_05.png", R.mipmap.icon_light_makeup_eyebrow_05, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_06("MAKEUP_EYEBROW_06", "light_makeup/eyebrow/mu_eyebrow_06.png", R.mipmap.icon_light_makeup_eyebrow_06, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_07("MAKEUP_EYEBROW_07", "light_makeup/eyebrow/mu_eyebrow_07.png", R.mipmap.icon_light_makeup_eyebrow_07, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_08("MAKEUP_EYEBROW_08", "light_makeup/eyebrow/mu_eyebrow_08.png", R.mipmap.icon_light_makeup_eyebrow_08, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_09("MAKEUP_EYEBROW_09", "light_makeup/eyebrow/mu_eyebrow_09.png", R.mipmap.icon_light_makeup_eyebrow_09, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_10("MAKEUP_EYEBROW_10", "light_makeup/eyebrow/mu_eyebrow_10.png", R.mipmap.icon_light_makeup_eyebrow_10, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_11("MAKEUP_EYEBROW_11", "light_makeup/eyebrow/mu_eyebrow_11.png", R.mipmap.icon_light_makeup_eyebrow_11, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_12("MAKEUP_EYEBROW_12", "light_makeup/eyebrow/mu_eyebrow_12.png", R.mipmap.icon_light_makeup_eyebrow_12, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_13("MAKEUP_EYEBROW_13", "light_makeup/eyebrow/mu_eyebrow_13.png", R.mipmap.icon_light_makeup_eyebrow_13, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_14("MAKEUP_EYEBROW_14", "light_makeup/eyebrow/mu_eyebrow_14.png", R.mipmap.icon_light_makeup_eyebrow_14, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_15("MAKEUP_EYEBROW_15", "light_makeup/eyebrow/mu_eyebrow_15.png", R.mipmap.icon_light_makeup_eyebrow_15, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_16("MAKEUP_EYEBROW_16", "light_makeup/eyebrow/mu_eyebrow_16.png", R.mipmap.icon_light_makeup_eyebrow_16, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_17("MAKEUP_EYEBROW_17", "light_makeup/eyebrow/mu_eyebrow_17.png", R.mipmap.icon_light_makeup_eyebrow_17, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_18("MAKEUP_EYEBROW_18", "light_makeup/eyebrow/mu_eyebrow_18.png", R.mipmap.icon_light_makeup_eyebrow_18, R.string.makeup_radio_eyebrow),
|
||||
|
||||
MAKEUP_EYEBROW_19("MAKEUP_EYEBROW_19", "light_makeup/eyebrow/mu_eyebrow_19.png", R.mipmap.icon_light_makeup_eyebrow_19, R.string.makeup_radio_eyebrow),
|
||||
|
||||
// 睫毛
|
||||
MAKEUP_EYELASH_01("MAKEUP_EYELASH_01", "light_makeup/eyelash/mu_eyelash_01.png", R.mipmap.icon_light_makeup_eyelash_01, R.string.makeup_radio_eyelash),
|
||||
|
||||
MAKEUP_EYELASH_02("MAKEUP_EYELASH_02", "light_makeup/eyelash/mu_eyelash_02.png", R.mipmap.icon_light_makeup_eyelash_02, R.string.makeup_radio_eyelash),
|
||||
|
||||
MAKEUP_EYELASH_03("MAKEUP_EYELASH_03", "light_makeup/eyelash/mu_eyelash_03.png", R.mipmap.icon_light_makeup_eyelash_03, R.string.makeup_radio_eyelash),
|
||||
|
||||
MAKEUP_EYELASH_04("MAKEUP_EYELASH_04", "light_makeup/eyelash/mu_eyelash_04.png", R.mipmap.icon_light_makeup_eyelash_04, R.string.makeup_radio_eyelash),
|
||||
|
||||
MAKEUP_EYELASH_05("MAKEUP_EYELASH_05", "light_makeup/eyelash/mu_eyelash_05.png", R.mipmap.icon_light_makeup_eyelash_05, R.string.makeup_radio_eyelash),
|
||||
|
||||
MAKEUP_EYELASH_06("MAKEUP_EYELASH_06", "light_makeup/eyelash/mu_eyelash_06.png", R.mipmap.icon_light_makeup_eyelash_06, R.string.makeup_radio_eyelash),
|
||||
|
||||
MAKEUP_EYELASH_07("MAKEUP_EYELASH_07", "light_makeup/eyelash/mu_eyelash_07.png", R.mipmap.icon_light_makeup_eyelash_07, R.string.makeup_radio_eyelash),
|
||||
|
||||
MAKEUP_EYELASH_08("MAKEUP_EYELASH_08", "light_makeup/eyelash/mu_eyelash_08.png", R.mipmap.icon_light_makeup_eyelash_08, R.string.makeup_radio_eyelash),
|
||||
|
||||
// 眼线
|
||||
MAKEUP_EYELINER_01("MAKEUP_EYELINER_01", "light_makeup/eyeliner/mu_eyeliner_01.png", R.mipmap.icon_light_makeup_eyeliner_01, R.string.makeup_radio_eye_liner),
|
||||
|
||||
MAKEUP_EYELINER_02("MAKEUP_EYELINER_02", "light_makeup/eyeliner/mu_eyeliner_02.png", R.mipmap.icon_light_makeup_eyeliner_02, R.string.makeup_radio_eye_liner),
|
||||
|
||||
MAKEUP_EYELINER_03("MAKEUP_EYELINER_03", "light_makeup/eyeliner/mu_eyeliner_03.png", R.mipmap.icon_light_makeup_eyeliner_03, R.string.makeup_radio_eye_liner),
|
||||
|
||||
MAKEUP_EYELINER_04("MAKEUP_EYELINER_04", "light_makeup/eyeliner/mu_eyeliner_04.png", R.mipmap.icon_light_makeup_eyeliner_04, R.string.makeup_radio_eye_liner),
|
||||
|
||||
MAKEUP_EYELINER_05("MAKEUP_EYELINER_05", "light_makeup/eyeliner/mu_eyeliner_05.png", R.mipmap.icon_light_makeup_eyeliner_05, R.string.makeup_radio_eye_liner),
|
||||
|
||||
MAKEUP_EYELINER_06("MAKEUP_EYELINER_06", "light_makeup/eyeliner/mu_eyeliner_06.png", R.mipmap.icon_light_makeup_eyeliner_06, R.string.makeup_radio_eye_liner),
|
||||
|
||||
MAKEUP_EYELINER_07("MAKEUP_EYELINER_07", "light_makeup/eyeliner/mu_eyeliner_07.png", R.mipmap.icon_light_makeup_eyeliner_07, R.string.makeup_radio_eye_liner),
|
||||
|
||||
MAKEUP_EYELINER_08("MAKEUP_EYELINER_08", "light_makeup/eyeliner/mu_eyeliner_08.png", R.mipmap.icon_light_makeup_eyeliner_08, R.string.makeup_radio_eye_liner),
|
||||
|
||||
// 美瞳
|
||||
MAKEUP_EYEPUPIL_01("MAKEUP_EYEPUPIL_01", "light_makeup/eyepupil/mu_eyepupil_01.png", R.mipmap.icon_light_makeup_eyepupil_01, R.string.makeup_radio_contact_lens),
|
||||
|
||||
MAKEUP_EYEPUPIL_02("MAKEUP_EYEPUPIL_02", "light_makeup/eyepupil/mu_eyepupil_02.png", R.mipmap.icon_light_makeup_eyepupil_02, R.string.makeup_radio_contact_lens),
|
||||
|
||||
MAKEUP_EYEPUPIL_03("MAKEUP_EYEPUPIL_03", "light_makeup/eyepupil/mu_eyepupil_03.png", R.mipmap.icon_light_makeup_eyepupil_03, R.string.makeup_radio_contact_lens),
|
||||
|
||||
MAKEUP_EYEPUPIL_04("MAKEUP_EYEPUPIL_04", "light_makeup/eyepupil/mu_eyepupil_04.png", R.mipmap.icon_light_makeup_eyepupil_04, R.string.makeup_radio_contact_lens),
|
||||
|
||||
MAKEUP_EYEPUPIL_05("MAKEUP_EYEPUPIL_05", "light_makeup/eyepupil/mu_eyepupil_05.png", R.mipmap.icon_light_makeup_eyepupil_05, R.string.makeup_radio_contact_lens),
|
||||
|
||||
MAKEUP_EYEPUPIL_06("MAKEUP_EYEPUPIL_06", "light_makeup/eyepupil/mu_eyepupil_06.png", R.mipmap.icon_light_makeup_eyepupil_06, R.string.makeup_radio_contact_lens),
|
||||
|
||||
MAKEUP_EYEPUPIL_07("MAKEUP_EYEPUPIL_07", "light_makeup/eyepupil/mu_eyepupil_07.png", R.mipmap.icon_light_makeup_eyepupil_07, R.string.makeup_radio_contact_lens),
|
||||
|
||||
MAKEUP_EYEPUPIL_08("MAKEUP_EYEPUPIL_08", "light_makeup/eyepupil/mu_eyepupil_08.png", R.mipmap.icon_light_makeup_eyepupil_08, R.string.makeup_radio_contact_lens),
|
||||
|
||||
MAKEUP_EYEPUPIL_09("MAKEUP_EYEPUPIL_09", "light_makeup/eyepupil/mu_eyepupil_09.png", R.mipmap.icon_light_makeup_eyepupil_09, R.string.makeup_radio_contact_lens),
|
||||
|
||||
// 眼影
|
||||
MAKEUP_EYE_SHADOW_01("MAKEUP_EYESHADOW_01", "light_makeup/eyeshadow/mu_eyeshadow_01.png", R.mipmap.icon_light_makeup_eyeshadow_01, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_02("MAKEUP_EYESHADOW_02", "light_makeup/eyeshadow/mu_eyeshadow_02.png", R.mipmap.icon_light_makeup_eyeshadow_02, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_03("MAKEUP_EYESHADOW_03", "light_makeup/eyeshadow/mu_eyeshadow_03.png", R.mipmap.icon_light_makeup_eyeshadow_03, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_04("MAKEUP_EYESHADOW_04", "light_makeup/eyeshadow/mu_eyeshadow_04.png", R.mipmap.icon_light_makeup_eyeshadow_04, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_05("MAKEUP_EYESHADOW_05", "light_makeup/eyeshadow/mu_eyeshadow_05.png", R.mipmap.icon_light_makeup_eyeshadow_05, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_06("MAKEUP_EYESHADOW_06", "light_makeup/eyeshadow/mu_eyeshadow_06.png", R.mipmap.icon_light_makeup_eyeshadow_06, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_07("MAKEUP_EYESHADOW_07", "light_makeup/eyeshadow/mu_eyeshadow_07.png", R.mipmap.icon_light_makeup_eyeshadow_07, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_08("MAKEUP_EYESHADOW_08", "light_makeup/eyeshadow/mu_eyeshadow_08.png", R.mipmap.icon_light_makeup_eyeshadow_08, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_09("MAKEUP_EYESHADOW_09", "light_makeup/eyeshadow/mu_eyeshadow_09.png", R.mipmap.icon_light_makeup_eyeshadow_09, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_10("MAKEUP_EYESHADOW_10", "light_makeup/eyeshadow/mu_eyeshadow_10.png", R.mipmap.icon_light_makeup_eyeshadow_10, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_11("MAKEUP_EYESHADOW_11", "light_makeup/eyeshadow/mu_eyeshadow_11.png", R.mipmap.icon_light_makeup_eyeshadow_11, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_12("MAKEUP_EYESHADOW_12", "light_makeup/eyeshadow/mu_eyeshadow_12.png", R.mipmap.icon_light_makeup_eyeshadow_12, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_13("MAKEUP_EYESHADOW_13", "light_makeup/eyeshadow/mu_eyeshadow_13.png", R.mipmap.icon_light_makeup_eyeshadow_13, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_14("MAKEUP_EYESHADOW_14", "light_makeup/eyeshadow/mu_eyeshadow_14.png", R.mipmap.icon_light_makeup_eyeshadow_14, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_15("MAKEUP_EYESHADOW_15", "light_makeup/eyeshadow/mu_eyeshadow_15.png", R.mipmap.icon_light_makeup_eyeshadow_15, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_16("MAKEUP_EYESHADOW_16", "light_makeup/eyeshadow/mu_eyeshadow_16.png", R.mipmap.icon_light_makeup_eyeshadow_16, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_17("MAKEUP_EYESHADOW_17", "light_makeup/eyeshadow/mu_eyeshadow_17.png", R.mipmap.icon_light_makeup_eyeshadow_17, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_18("MAKEUP_EYESHADOW_18", "light_makeup/eyeshadow/mu_eyeshadow_18.png", R.mipmap.icon_light_makeup_eyeshadow_18, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_19("MAKEUP_EYESHADOW_19", "light_makeup/eyeshadow/mu_eyeshadow_19.png", R.mipmap.icon_light_makeup_eyeshadow_19, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_20("MAKEUP_EYESHADOW_20", "light_makeup/eyeshadow/mu_eyeshadow_20.png", R.mipmap.icon_light_makeup_eyeshadow_20, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_21("MAKEUP_EYESHADOW_21", "light_makeup/eyeshadow/mu_eyeshadow_21.png", R.mipmap.icon_light_makeup_eyeshadow_21, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
MAKEUP_EYE_SHADOW_22("MAKEUP_EYESHADOW_22", "light_makeup/eyeshadow/mu_eyeshadow_22.png", R.mipmap.icon_light_makeup_eyeshadow_22, R.string.makeup_radio_eye_shadow),
|
||||
|
||||
// 口红
|
||||
MAKEUP_LIPSTICK_01("MAKEUP_LIPSTICK_01", "light_makeup/lipstick/mu_lip_01.json", R.mipmap.icon_light_makeup_lip_01, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_02("MAKEUP_LIPSTICK_02", "light_makeup/lipstick/mu_lip_02.json", R.mipmap.icon_light_makeup_lip_02, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_03("MAKEUP_LIPSTICK_03", "light_makeup/lipstick/mu_lip_03.json", R.mipmap.icon_light_makeup_lip_03, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_10("MAKEUP_LIPSTICK_10", "light_makeup/lipstick/mu_lip_10.json", R.mipmap.icon_light_makeup_lip_10, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_11("MAKEUP_LIPSTICK_11", "light_makeup/lipstick/mu_lip_11.json", R.mipmap.icon_light_makeup_lip_12, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_12("MAKEUP_LIPSTICK_12", "light_makeup/lipstick/mu_lip_12.json", R.mipmap.icon_light_makeup_lip_12, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_13("MAKEUP_LIPSTICK_13", "light_makeup/lipstick/mu_lip_13.json", R.mipmap.icon_light_makeup_lip_13, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_14("MAKEUP_LIPSTICK_14", "light_makeup/lipstick/mu_lip_14.json", R.mipmap.icon_light_makeup_lip_14, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_15("MAKEUP_LIPSTICK_15", "light_makeup/lipstick/mu_lip_15.json", R.mipmap.icon_light_makeup_lip_15, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_16("MAKEUP_LIPSTICK_16", "light_makeup/lipstick/mu_lip_16.json", R.mipmap.icon_light_makeup_lip_16, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_17("MAKEUP_LIPSTICK_17", "light_makeup/lipstick/mu_lip_17.json", R.mipmap.icon_light_makeup_lip_17, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_18("MAKEUP_LIPSTICK_18", "light_makeup/lipstick/mu_lip_18.json", R.mipmap.icon_light_makeup_lip_18, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_19("MAKEUP_LIPSTICK_19", "light_makeup/lipstick/mu_lip_19.json", R.mipmap.icon_light_makeup_lip_19, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_20("MAKEUP_LIPSTICK_20", "light_makeup/lipstick/mu_lip_20.json", R.mipmap.icon_light_makeup_lip_20, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_21("MAKEUP_LIPSTICK_21", "light_makeup/lipstick/mu_lip_21.json", R.mipmap.icon_light_makeup_lip_21, R.string.makeup_radio_lipstick),
|
||||
|
||||
MAKEUP_LIPSTICK_22("MAKEUP_LIPSTICK_22", "light_makeup/lipstick/mu_lip_22.json", R.mipmap.icon_light_makeup_lip_22, R.string.makeup_radio_lipstick);
|
||||
|
||||
|
||||
private final String key;
|
||||
private final String path;
|
||||
private final int iconRes;
|
||||
private final int strRes;
|
||||
|
||||
LightMakeUpEnum(String key, String path, int iconRes, int strRes) {
|
||||
this.key = key;
|
||||
this.path = path;
|
||||
this.iconRes = iconRes;
|
||||
this.strRes = strRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取口红颜色
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public FUColorRGBData getLipColorRGBData() {
|
||||
double[] colorArray = loadRgbaColorFromLocal(FaceUnityData.mApplication, path);
|
||||
if (colorArray != null && colorArray.length == 4) {
|
||||
return new FUColorRGBData(colorArray[0] * 255, colorArray[1] * 255, colorArray[2] * 255, colorArray[3] * 255);
|
||||
}
|
||||
return new FUColorRGBData(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
/**
|
||||
* 读取 RGBA 颜色数据
|
||||
*
|
||||
* @param context
|
||||
* @param path path
|
||||
* @return
|
||||
*/
|
||||
public static double[] loadRgbaColorFromLocal(Context context, String path) {
|
||||
InputStream inputStream = FileUtils.readInputStreamByPath(context, path);
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
byte[] bytes = new byte[inputStream.available()];
|
||||
inputStream.read(bytes);
|
||||
JSONObject jsonObject = new JSONObject(new String(bytes));
|
||||
JSONArray jsonArray = jsonObject.optJSONArray("rgba");
|
||||
double[] colorArray = new double[jsonArray.length()];
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
colorArray[i] = jsonArray.optDouble(i);
|
||||
}
|
||||
return colorArray;
|
||||
} catch (IOException | JSONException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,489 @@
|
||||
package com.yunbao.faceunity.repo;
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.faceunity.core.controller.makeup.MakeupParam;
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.entity.FUColorRGBData;
|
||||
import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum;
|
||||
import com.faceunity.core.model.makeup.Makeup;
|
||||
import com.faceunity.core.utils.FileUtils;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
import com.yunbao.faceunity.entity.MakeupCombinationBean;
|
||||
import com.yunbao.faceunity.entity.MakeupCustomBean;
|
||||
import com.yunbao.faceunity.entity.MakeupCustomClassBean;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
import com.yunbao.faceunity.utils.FaceUnityData;
|
||||
import com.yunbao.faceunity.entity.MakeupCombinationBean.TypeEnum;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* DESC:美妆数据构造
|
||||
* Created on 2021/3/28
|
||||
*/
|
||||
public class MakeupSource {
|
||||
public static String BUNDLE_FACE_MAKEUP = "graphics" + File.separator + "face_makeup.bundle";
|
||||
|
||||
|
||||
//region 组合妆容
|
||||
|
||||
/**
|
||||
* 构造美妆组合妆容配置
|
||||
*
|
||||
* @return ArrayList<MakeupCombinationBean>
|
||||
*/
|
||||
public static ArrayList<MakeupCombinationBean> buildCombinations() {
|
||||
ArrayList<MakeupCombinationBean> combinations = new ArrayList<MakeupCombinationBean>();
|
||||
String jsonDir = FaceUnityConfig.MAKEUP_RESOURCE_JSON_DIR;
|
||||
String bundleDir = FaceUnityConfig.MAKEUP_RESOURCE_COMBINATION_BUNDLE_DIR;
|
||||
combinations.add(new MakeupCombinationBean("origin", TypeEnum.TYPE_NONE, R.mipmap.icon_control_none, R.string.makeup_radio_remove, null, "", FaceBeautyFilterEnum.ZIRAN_2, 1.0,0.0,FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("diadiatu", TypeEnum.TYPE_THEME_MAIN, R.mipmap.icon_makeup_combination_diadiatu, R.string.makeup_combination_diadiatu, bundleDir + "diadiatu.bundle", jsonDir + "diadiatu.json", FaceBeautyFilterEnum.ORIGIN, 0.68,FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("dongling", TypeEnum.TYPE_THEME_MAIN, R.mipmap.icon_makeup_combination_freezing_age, R.string.makeup_combination_dongling, bundleDir + "dongling.bundle", jsonDir + "dongling.json", FaceBeautyFilterEnum.ORIGIN, 0.68,FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("guofeng", TypeEnum.TYPE_THEME_MAIN, R.mipmap.icon_makeup_combination_guo_feng, R.string.makeup_combination_guofeng, bundleDir + "guofeng.bundle", jsonDir + "guofeng.json", FaceBeautyFilterEnum.ORIGIN, 0.6,FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("hunxie", TypeEnum.TYPE_THEME_MAIN, R.mipmap.icon_makeup_combination_mixed_race, R.string.makeup_combination_hunxie, bundleDir + "hunxie.bundle", jsonDir + "hunxie.json", FaceBeautyFilterEnum.ORIGIN, 0.6,FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("jianling", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_age, R.string.makeup_combination_jianling, bundleDir + "jianling.bundle", jsonDir + "jianling.json", FaceBeautyFilterEnum.ZHIGANHUI_1, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("nuandong", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_warm_winter, R.string.makeup_combination_nuandong, bundleDir + "nuandong.bundle", jsonDir + "nuandong.json", FaceBeautyFilterEnum.ZHIGANHUI_2, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("hongfeng", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_red_maple, R.string.makeup_combination_hongfeng, bundleDir + "hongfeng.bundle", jsonDir + "hongfeng.json", FaceBeautyFilterEnum.ZHIGANHUI_3, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("rose", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_rose, R.string.makeup_combination_rose, bundleDir + "rose.bundle", jsonDir + "rose.json", FaceBeautyFilterEnum.ZHIGANHUI_2, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("shaonv", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_girl, R.string.makeup_combination_shaonv, bundleDir + "shaonv.bundle", jsonDir + "shaonv.json", FaceBeautyFilterEnum.ZHIGANHUI_4, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("ziyun", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_purple_rhyme, R.string.makeup_combination_ziyun, bundleDir + "ziyun.bundle", jsonDir + "ziyun.json", FaceBeautyFilterEnum.ZHIGANHUI_1, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("yanshimao", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_bored_cat, R.string.makeup_combination_yanshimao, bundleDir + "yanshimao.bundle", jsonDir + "yanshimao.json", FaceBeautyFilterEnum.ZHIGANHUI_5, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("renyu", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_mermaid, R.string.makeup_combination_renyu, bundleDir + "renyu.bundle", jsonDir + "renyu.json", FaceBeautyFilterEnum.ZHIGANHUI_1, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("chuqiu", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_early_autumn, R.string.makeup_combination_chuqiu, bundleDir + "chuqiu.bundle", jsonDir + "chuqiu.json", FaceBeautyFilterEnum.ZHIGANHUI_6, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("qianzhihe", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_paper_cranes, R.string.makeup_combination_qianzhihe, bundleDir + "qianzhihe.bundle", jsonDir + "qianzhihe.json", FaceBeautyFilterEnum.ZHIGANHUI_2, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("chaomo", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_supermodel, R.string.makeup_combination_chaomo, bundleDir + "chaomo.bundle", jsonDir + "chaomo.json", FaceBeautyFilterEnum.ZHIGANHUI_7, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("chuju", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_daisy, R.string.makeup_combination_chuju, bundleDir + "chuju.bundle", jsonDir + "chuju.json", FaceBeautyFilterEnum.ZHIGANHUI_8, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("gangfeng", TypeEnum.TYPE_THEME_SUB, R.mipmap.icon_makeup_combination_harbour_wind, R.string.makeup_combination_gangfeng, bundleDir + "gangfeng.bundle", jsonDir + "gangfeng.json", FaceBeautyFilterEnum.ZIRAN_8, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("xinggan", TypeEnum.TYPE_DAILY, R.mipmap.icon_makeup_combination_sexy, R.string.makeup_combination_sexy, bundleDir + "xinggan.bundle", jsonDir + "xinggan.json", FaceBeautyFilterEnum.ZIRAN_4, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("tianmei", TypeEnum.TYPE_DAILY, R.mipmap.icon_makeup_combination_sweet, R.string.makeup_combination_sweet, bundleDir + "tianmei.bundle", jsonDir + "tianmei.json", FaceBeautyFilterEnum.ZIRAN_4, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("linjia", TypeEnum.TYPE_DAILY, R.mipmap.icon_makeup_combination_neighbor_girl, R.string.makeup_combination_neighbor, bundleDir + "linjia.bundle", jsonDir + "linjia.json", FaceBeautyFilterEnum.ZIRAN_4, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("oumei", TypeEnum.TYPE_DAILY, R.mipmap.icon_makeup_combination_occident, R.string.makeup_combination_occident, bundleDir + "oumei.bundle", jsonDir + "oumei.json", FaceBeautyFilterEnum.ZIRAN_4, FaceParam.FACE_MAKEUP));
|
||||
combinations.add(new MakeupCombinationBean("wumei", TypeEnum.TYPE_DAILY, R.mipmap.icon_makeup_combination_charming, R.string.makeup_combination_charming, bundleDir + "wumei.bundle", jsonDir + "wumei.json", FaceBeautyFilterEnum.ZIRAN_4, FaceParam.FACE_MAKEUP));
|
||||
return combinations;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造美妆模型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Makeup getMakeupModel(MakeupCombinationBean bean) {
|
||||
Makeup makeupModel;
|
||||
if (TypeEnum.TYPE_THEME_MAIN == bean.getType() && bean.getBundlePath() != null && bean.getBundlePath().trim().length() > 0) {
|
||||
makeupModel = new Makeup(new FUBundleData(bean.getBundlePath()));
|
||||
//新的组合妆容设置滤镜scale
|
||||
makeupModel.setCurrentFilterScale(bean.getFilterScale());
|
||||
} else {
|
||||
makeupModel = new Makeup(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_MAKEUP));
|
||||
}
|
||||
|
||||
if (bean.getKey().equals("origin")) {
|
||||
return makeupModel;
|
||||
}
|
||||
|
||||
if ((TypeEnum.TYPE_THEME_SUB == bean.getType() || TypeEnum.TYPE_DAILY == bean.getType()) && bean.getBundlePath() != null && bean.getBundlePath().trim().length() > 0)
|
||||
makeupModel.setCombinedConfig(new FUBundleData(bean.getBundlePath()));
|
||||
|
||||
makeupModel.setMakeupIntensity(bean.getIntensity());
|
||||
if (bean.getJsonPathParams() == null) {
|
||||
bean.setJsonPathParams(getLocalParams(bean.getJsonPath()));
|
||||
}
|
||||
LinkedHashMap<String, Object> params = bean.getJsonPathParams();
|
||||
|
||||
//支持自定义,所以需要知道选中了妆容的哪一些项
|
||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
String key = entry.getKey();
|
||||
if (value instanceof double[] && ((double[]) value).length > 4) {
|
||||
int count = ((double[]) value).length / 4;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (i == 0) {
|
||||
if (makeupSetMapping.containsKey(key)) {
|
||||
makeupSetMapping.get(key).setValue(makeupModel, value);
|
||||
}
|
||||
} else {
|
||||
if (makeupSetMapping.containsKey(key + (i + 1))) {
|
||||
makeupSetMapping.get(key + (i + 1)).setValue(makeupModel, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (makeupSetMapping.containsKey(key)) {
|
||||
makeupSetMapping.get(key).setValue(makeupModel, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return makeupModel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 读取本地参数配置
|
||||
*
|
||||
* @param jsonPath String json文件路径
|
||||
* @return LinkedHashMap<String, Any>
|
||||
*/
|
||||
private static LinkedHashMap<String, Object> getLocalParams(String jsonPath) {
|
||||
LinkedHashMap<String, Object> map = new LinkedHashMap(32);
|
||||
map.put(MakeupParam.LIP_INTENSITY, 0.0);
|
||||
map.put(MakeupParam.EYE_LINER_INTENSITY, 0.0);
|
||||
map.put(MakeupParam.BLUSHER_INTENSITY, 0.0);
|
||||
map.put(MakeupParam.PUPIL_INTENSITY, 0.0);
|
||||
map.put(MakeupParam.EYE_BROW_INTENSITY, 0.0);
|
||||
map.put(MakeupParam.EYE_SHADOW_INTENSITY, 0.0);
|
||||
map.put(MakeupParam.EYELASH_INTENSITY, 0.0);
|
||||
map.put(MakeupParam.FOUNDATION_INTENSITY, 0.0);
|
||||
map.put(MakeupParam.HIGHLIGHT_INTENSITY, 0.0);
|
||||
map.put(MakeupParam.SHADOW_INTENSITY, 0.0);
|
||||
LinkedHashMap<String, Object> jsonParam = FileUtils.INSTANCE.loadParamsFromLocal(FaceUnityData.mApplication, jsonPath);
|
||||
for (Map.Entry<String, Object> entry : jsonParam.entrySet()) {
|
||||
if (entry.getKey().startsWith("tex_")) {
|
||||
if (entry.getValue() instanceof String && ((String) entry.getValue()).contains(".bundle")) {
|
||||
map.put(entry.getKey(), FaceUnityConfig.MAKEUP_RESOURCE_ITEM_BUNDLE_DIR + entry.getValue());
|
||||
}
|
||||
} else {
|
||||
map.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
interface MakeupSetParam {
|
||||
/**
|
||||
* 模型属性赋值
|
||||
*
|
||||
* @param makeup
|
||||
* @param value
|
||||
*/
|
||||
void setValue(Makeup makeup, Object value);
|
||||
|
||||
}
|
||||
|
||||
/*美妆映射模型*/
|
||||
public static HashMap<String, MakeupSetParam> makeupSetMapping = new HashMap<String, MakeupSetParam>() {
|
||||
{
|
||||
put(MakeupParam.LIP_TYPE, (makeup, value) -> makeup.setLipType((int) value));
|
||||
put(MakeupParam.IS_TWO_COLOR, (makeup, value) -> makeup.setEnableTwoLipColor((int) value == 1));
|
||||
put(MakeupParam.MAKEUP_LIP_HIGH_LIGHT_ENABLE, (makeup, value) -> makeup.setLipHighLightEnable((int) value == 1));
|
||||
put(MakeupParam.MAKEUP_LIP_HIGH_LIGHT_STRENGTH, (makeup, value) -> makeup.setLipHighLightStrength((double) value));
|
||||
put(MakeupParam.BROW_WARP, (makeup, value) -> makeup.setEnableBrowWarp((double) value == 1.0));
|
||||
put(MakeupParam.BROW_WARP_TYPE, (makeup, value) -> makeup.setBrowWarpType((int) value));
|
||||
/*强度*/
|
||||
put(MakeupParam.MAKEUP_INTENSITY, (makeup, value) -> makeup.setMakeupIntensity((double) value));
|
||||
put(MakeupParam.LIP_INTENSITY, (makeup, value) -> makeup.setLipIntensity((double) value));
|
||||
put(MakeupParam.EYE_LINER_INTENSITY, (makeup, value) -> makeup.setEyeLineIntensity((double) value));
|
||||
put(MakeupParam.BLUSHER_INTENSITY, (makeup, value) -> makeup.setBlusherIntensity((double) value));
|
||||
put(MakeupParam.PUPIL_INTENSITY, (makeup, value) -> makeup.setPupilIntensity((double) value));
|
||||
put(MakeupParam.EYE_BROW_INTENSITY, (makeup, value) -> makeup.setEyeBrowIntensity((double) value));
|
||||
put(MakeupParam.EYE_SHADOW_INTENSITY, (makeup, value) -> makeup.setEyeShadowIntensity((double) value));
|
||||
put(MakeupParam.EYELASH_INTENSITY, (makeup, value) -> makeup.setEyeLashIntensity((double) value));
|
||||
put(MakeupParam.FOUNDATION_INTENSITY, (makeup, value) -> makeup.setFoundationIntensity((double) value));
|
||||
put(MakeupParam.HIGHLIGHT_INTENSITY, (makeup, value) -> makeup.setHeightLightIntensity((double) value));
|
||||
put(MakeupParam.SHADOW_INTENSITY, (makeup, value) -> makeup.setShadowIntensity((double) value));
|
||||
/*子项妆容贴图*/
|
||||
put(MakeupParam.TEX_LIP, (makeup, value) -> makeup.setLipBundle(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_EYE_BROW, (makeup, value) -> makeup.setEyeBrowBundle(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_EYE_SHADOW, (makeup, value) -> makeup.setEyeShadowBundle(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_EYE_SHADOW2, (makeup, value) -> makeup.setEyeShadowBundle2(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_EYE_SHADOW3, (makeup, value) -> makeup.setEyeShadowBundle3(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_EYE_SHADOW4, (makeup, value) -> makeup.setEyeShadowBundle4(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_PUPIL, (makeup, value) -> makeup.setPupilBundle(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_EYE_LASH, (makeup, value) -> makeup.setEyeLashBundle(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_EYE_LINER, (makeup, value) -> makeup.setEyeLinerBundle(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_BLUSHER, (makeup, value) -> makeup.setBlusherBundle(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_BLUSHER2, (makeup, value) -> makeup.setBlusherBundle2(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_FOUNDATION, (makeup, value) -> makeup.setFoundationBundle(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_HIGH_LIGHT, (makeup, value) -> makeup.setHighLightBundle(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
put(MakeupParam.TEX_SHADOW, (makeup, value) -> makeup.setShadowBundle(((String) value).endsWith(".bundle") ? new FUBundleData((String) value) : null));
|
||||
/*子项妆容颜色*/
|
||||
put(MakeupParam.MAKEUP_LIP_COLOR, (makeup, value) -> makeup.setLipColor(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_LIP_COLOR_V2, (makeup, value) -> makeup.setLipColorV2(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_LIP_COLOR2, (makeup, value) -> makeup.setLipColor2(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_EYE_LINER_COLOR, (makeup, value) -> makeup.setEyeLinerColor(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_EYE_LASH_COLOR, (makeup, value) -> makeup.setEyeLashColor(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_BLUSHER_COLOR, (makeup, value) -> makeup.setBlusherColor(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_BLUSHER_COLOR2, (makeup, value) -> makeup.setBlusherColor2(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_FOUNDATION_COLOR, (makeup, value) -> makeup.setFoundationColor(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_HIGH_LIGHT_COLOR, (makeup, value) -> makeup.setHighLightColor(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_SHADOW_COLOR, (makeup, value) -> makeup.setShadowColor(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_EYE_BROW_COLOR, (makeup, value) -> makeup.setEyeBrowColor(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_PUPIL_COLOR, (makeup, value) -> makeup.setPupilColor(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_EYE_SHADOW_COLOR, (makeup, value) -> makeup.setEyeShadowColor(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_EYE_SHADOW_COLOR2, (makeup, value) -> makeup.setEyeShadowColor2(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_EYE_SHADOW_COLOR3, (makeup, value) -> makeup.setEyeShadowColor3(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_EYE_SHADOW_COLOR4, (makeup, value) -> makeup.setEyeShadowColor4(buildFUColorRGBData(value)));
|
||||
put(MakeupParam.MAKEUP_EYE_BROW_COLOR, (makeup, value) -> makeup.setEyeBrowColor(buildFUColorRGBData(value)));
|
||||
/* 图层混合模式 */
|
||||
put(MakeupParam.BLEND_TEX_EYE_SHADOW, (makeup, value) -> makeup.setEyeShadowTexBlend((int) value));
|
||||
put(MakeupParam.BLEND_TEX_EYE_SHADOW2, (makeup, value) -> makeup.setEyeShadowTexBlend2((int) value));
|
||||
put(MakeupParam.BLEND_TEX_EYE_SHADOW3, (makeup, value) -> makeup.setEyeShadowTexBlend3((int) value));
|
||||
put(MakeupParam.BLEND_TEX_EYE_SHADOW4, (makeup, value) -> makeup.setEyeShadowTexBlend4((int) value));
|
||||
put(MakeupParam.BLEND_TEX_EYE_LASH, (makeup, value) -> makeup.setEyeLashTexBlend((int) value));
|
||||
put(MakeupParam.BLEND_TEX_EYE_LINER, (makeup, value) -> makeup.setEyeLinerTexBlend((int) value));
|
||||
put(MakeupParam.BLEND_TEX_BLUSHER, (makeup, value) -> makeup.setBlusherTexBlend((int) value));
|
||||
put(MakeupParam.BLEND_TEX_BLUSHER2, (makeup, value) -> makeup.setBlusherTexBlend2((int) value));
|
||||
put(MakeupParam.BLEND_TEX_PUPIL, (makeup, value) -> makeup.setPupilTexBlend((int) value));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 构造颜色模型
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
public static FUColorRGBData buildFUColorRGBData(Object object) {
|
||||
if (object instanceof double[]) {
|
||||
double[] array = (double[]) object;
|
||||
if (array.length == 4) {
|
||||
return new FUColorRGBData(array[0] * 255, array[1] * 255, array[2] * 255, array[3] * 255);
|
||||
}
|
||||
}
|
||||
return new FUColorRGBData(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
//endregion 组合妆容
|
||||
|
||||
// region 子妆容
|
||||
|
||||
/* 粉底 */
|
||||
public static String FACE_MAKEUP_TYPE_FOUNDATION = "FOUNDATION";
|
||||
/* 口红 */
|
||||
public static String FACE_MAKEUP_TYPE_LIP_STICK = "STICK";
|
||||
/* 腮红 */
|
||||
public static String FACE_MAKEUP_TYPE_BLUSHER = "BLUSHER";
|
||||
/* 眉毛 */
|
||||
public static String FACE_MAKEUP_TYPE_EYE_BROW = "EYE_BROW";
|
||||
/* 眼影 */
|
||||
public static String FACE_MAKEUP_TYPE_EYE_SHADOW = "EYE_SHADOW";
|
||||
/* 眼线 */
|
||||
public static String FACE_MAKEUP_TYPE_EYE_LINER = "EYE_LINER";
|
||||
/* 睫毛 */
|
||||
public static String FACE_MAKEUP_TYPE_EYE_LASH = "EYE_LASH";
|
||||
/* 高光 */
|
||||
public static String FACE_MAKEUP_TYPE_HIGH_LIGHT = "HIGHLIGHT";
|
||||
/* 阴影 */
|
||||
public static String FACE_MAKEUP_TYPE_SHADOW = "SHADOW";
|
||||
/* 美瞳 */
|
||||
public static String FACE_MAKEUP_TYPE_EYE_PUPIL = "EYE_PUPIL";
|
||||
|
||||
/**
|
||||
* 构造美妆子项类别
|
||||
*/
|
||||
public static ArrayList<MakeupCustomClassBean> buildCustomClasses() {
|
||||
ArrayList<MakeupCustomClassBean> classes = new ArrayList();
|
||||
classes.add(new MakeupCustomClassBean(R.string.makeup_radio_foundation, FACE_MAKEUP_TYPE_FOUNDATION,FaceParam.FACE_MAKEUP_TYPE_FOUNDATION));
|
||||
classes.add(new MakeupCustomClassBean(R.string.makeup_radio_lipstick, FACE_MAKEUP_TYPE_LIP_STICK,FaceParam.FACE_MAKEUP_TYPE_LIP_STICK));
|
||||
classes.add(new MakeupCustomClassBean(R.string.makeup_radio_blusher, FACE_MAKEUP_TYPE_BLUSHER,FaceParam.FACE_MAKEUP_TYPE_BLUSHER));
|
||||
classes.add(new MakeupCustomClassBean(R.string.makeup_radio_eyebrow, FACE_MAKEUP_TYPE_EYE_BROW,FaceParam.FACE_MAKEUP_TYPE_EYE_BROW));
|
||||
classes.add(new MakeupCustomClassBean(R.string.makeup_radio_eye_shadow, FACE_MAKEUP_TYPE_EYE_SHADOW,FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW));
|
||||
classes.add(new MakeupCustomClassBean(R.string.makeup_radio_eye_liner, FACE_MAKEUP_TYPE_EYE_LINER,FaceParam.FACE_MAKEUP_TYPE_EYE_LINER));
|
||||
classes.add(new MakeupCustomClassBean(R.string.makeup_radio_eyelash, FACE_MAKEUP_TYPE_EYE_LASH,FaceParam.FACE_MAKEUP_TYPE_EYE_LASH));
|
||||
classes.add(new MakeupCustomClassBean(R.string.makeup_radio_highlight, FACE_MAKEUP_TYPE_HIGH_LIGHT,FaceParam.FACE_MAKEUP_TYPE_HIGH_LIGHT));
|
||||
classes.add(new MakeupCustomClassBean(R.string.makeup_radio_shadow, FACE_MAKEUP_TYPE_SHADOW,FaceParam.FACE_MAKEUP_TYPE_SHADOW));
|
||||
classes.add(new MakeupCustomClassBean(R.string.makeup_radio_contact_lens, FACE_MAKEUP_TYPE_EYE_PUPIL,FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
return classes;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String,ArrayList<MakeupCustomBean>> buildCustomItemParams(){
|
||||
return buildCustomItemParams(MakeupSource.buildMakeUpColorMap());
|
||||
}
|
||||
/**
|
||||
* 美妆单项妆容配置参数
|
||||
*
|
||||
* @return LinkedHashMap<String, ArrayList < MakeupCustomBean>>
|
||||
*/
|
||||
public static LinkedHashMap<String, ArrayList<MakeupCustomBean>> buildCustomItemParams(LinkedHashMap<String, ArrayList<double[]>> colorMap) {
|
||||
LinkedHashMap<String, ArrayList<MakeupCustomBean>> mCustomItems = new LinkedHashMap<>();
|
||||
/*粉底*/
|
||||
ArrayList<MakeupCustomBean> makeupItems = new ArrayList(6);
|
||||
makeupItems.add(new MakeupCustomBean(R.string.makeup_radio_remove, getDrawable(R.mipmap.icon_control_none),FaceParam.FACE_MAKEUP_TYPE_FOUNDATION));
|
||||
ArrayList<double[]> list = colorMap.get("color_mu_style_foundation_01");
|
||||
for (int i = 3; i < 8; i++) {
|
||||
double[] colors = list.get(i);
|
||||
ColorDrawable drawable = new ColorDrawable(Color.argb((int) (colors[3] * 255), (int) (colors[0] * 255), (int) (colors[1] * 255), (int) (colors[2] * 255)));
|
||||
makeupItems.add(new MakeupCustomBean(0, drawable,FaceParam.FACE_MAKEUP_TYPE_FOUNDATION));
|
||||
}
|
||||
mCustomItems.put(FACE_MAKEUP_TYPE_FOUNDATION, makeupItems);
|
||||
|
||||
|
||||
/*口红*/
|
||||
mCustomItems.put(FACE_MAKEUP_TYPE_LIP_STICK, new ArrayList<MakeupCustomBean>() {
|
||||
{
|
||||
add(new MakeupCustomBean(R.string.makeup_radio_remove, getDrawable(R.mipmap.icon_control_none),FaceParam.FACE_MAKEUP_TYPE_LIP_STICK));
|
||||
add(new MakeupCustomBean(R.string.makeup_lip_fog, getDrawable(R.mipmap.icon_makeup_lip_fog), colorMap.get("color_mu_style_lip_01"),FaceParam.FACE_MAKEUP_TYPE_LIP_STICK));
|
||||
add(new MakeupCustomBean(R.string.makeup_lip_moist1, getDrawable(R.mipmap.icon_makeup_lip_moist), colorMap.get("color_mu_style_lip_01"),FaceParam.FACE_MAKEUP_TYPE_LIP_STICK));
|
||||
add(new MakeupCustomBean(R.string.makeup_lip_moist2, getDrawable(R.mipmap.icon_makeup_lip_water), colorMap.get("color_mu_style_lip_01"),FaceParam.FACE_MAKEUP_TYPE_LIP_STICK));
|
||||
add(new MakeupCustomBean(R.string.makeup_lip_pearl, getDrawable(R.mipmap.icon_makeup_lip_pearl), colorMap.get("color_mu_style_lip_01"),FaceParam.FACE_MAKEUP_TYPE_LIP_STICK));
|
||||
add(new MakeupCustomBean(R.string.makeup_lip_bitelip, getDrawable(R.mipmap.icon_makeup_lip_beitelip), colorMap.get("color_mu_style_lip_01"),FaceParam.FACE_MAKEUP_TYPE_LIP_STICK));
|
||||
}
|
||||
});
|
||||
|
||||
/*腮红*/
|
||||
mCustomItems.put(FACE_MAKEUP_TYPE_BLUSHER, new ArrayList<MakeupCustomBean>() {
|
||||
{
|
||||
add(new MakeupCustomBean(R.string.makeup_radio_remove, getDrawable(R.mipmap.icon_control_none),FaceParam.FACE_MAKEUP_TYPE_BLUSHER));
|
||||
add(new MakeupCustomBean(R.string.makeup_blusher_apple, getDrawable(R.mipmap.icon_makeup_blush_01), colorMap.get("color_mu_style_blush_01"),FaceParam.FACE_MAKEUP_TYPE_BLUSHER));
|
||||
add(new MakeupCustomBean(R.string.makeup_blusher_fan, getDrawable(R.mipmap.icon_makeup_blush_02), colorMap.get("color_mu_style_blush_02"),FaceParam.FACE_MAKEUP_TYPE_BLUSHER));
|
||||
add(new MakeupCustomBean(R.string.makeup_blusher_eye_corner, getDrawable(R.mipmap.icon_makeup_blush_03), colorMap.get("color_mu_style_blush_03"),FaceParam.FACE_MAKEUP_TYPE_BLUSHER));
|
||||
add(new MakeupCustomBean(R.string.makeup_blusher_slight_drunk, getDrawable(R.mipmap.icon_makeup_blush_04), colorMap.get("color_mu_style_blush_04"),FaceParam.FACE_MAKEUP_TYPE_BLUSHER));
|
||||
}
|
||||
});
|
||||
/*眉毛*/
|
||||
mCustomItems.put(FACE_MAKEUP_TYPE_EYE_BROW, new ArrayList<MakeupCustomBean>() {
|
||||
{
|
||||
add(new MakeupCustomBean(R.string.makeup_radio_remove, getDrawable(R.mipmap.icon_control_none),FaceParam.FACE_MAKEUP_TYPE_EYE_BROW));
|
||||
add(new MakeupCustomBean(R.string.makeup_eyebrow_willow, getDrawable(R.mipmap.icon_makeup_eyebrow_01), colorMap.get("color_mu_style_eyebrow_01"),FaceParam.FACE_MAKEUP_TYPE_EYE_BROW));
|
||||
add(new MakeupCustomBean(R.string.makeup_eyebrow_wild, getDrawable(R.mipmap.icon_makeup_eyebrow_02), colorMap.get("color_mu_style_eyebrow_01"),FaceParam.FACE_MAKEUP_TYPE_EYE_BROW));
|
||||
add(new MakeupCustomBean(R.string.makeup_eyebrow_classical, getDrawable(R.mipmap.icon_makeup_eyebrow_03), colorMap.get("color_mu_style_eyebrow_01"),FaceParam.FACE_MAKEUP_TYPE_EYE_BROW));
|
||||
add(new MakeupCustomBean(R.string.makeup_eyebrow_standard, getDrawable(R.mipmap.icon_makeup_eyebrow_04), colorMap.get("color_mu_style_eyebrow_01"),FaceParam.FACE_MAKEUP_TYPE_EYE_BROW));
|
||||
}
|
||||
});
|
||||
|
||||
/*眼影*/
|
||||
mCustomItems.put(FACE_MAKEUP_TYPE_EYE_SHADOW, new ArrayList<MakeupCustomBean>() {
|
||||
{
|
||||
add(new MakeupCustomBean(R.string.makeup_radio_remove, getDrawable(R.mipmap.icon_control_none),FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_shadow_single, getDrawable(R.mipmap.icon_makeup_eyeshadow_01), colorMap.get("color_mu_style_eyeshadow_01"),FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_shadow_double1, getDrawable(R.mipmap.icon_makeup_eyeshadow_02), colorMap.get("color_mu_style_eyeshadow_02"),FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_shadow_double2, getDrawable(R.mipmap.icon_makeup_eyeshadow_03), colorMap.get("color_mu_style_eyeshadow_03"),FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_shadow_double3, getDrawable(R.mipmap.icon_makeup_eyeshadow_04), colorMap.get("color_mu_style_eyeshadow_04"),FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_shadow_triple1, getDrawable(R.mipmap.icon_makeup_eyeshadow_05), colorMap.get("color_mu_style_eyeshadow_05"),FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_shadow_triple2, getDrawable(R.mipmap.icon_makeup_eyeshadow_06), colorMap.get("color_mu_style_eyeshadow_06"),FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW));
|
||||
}
|
||||
});
|
||||
|
||||
/*眼线*/
|
||||
mCustomItems.put(FACE_MAKEUP_TYPE_EYE_LINER, new ArrayList<MakeupCustomBean>() {
|
||||
{
|
||||
add(new MakeupCustomBean(R.string.makeup_radio_remove, getDrawable(R.mipmap.icon_control_none),FaceParam.FACE_MAKEUP_TYPE_EYE_LINER));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_linear_cat, getDrawable(R.mipmap.icon_makeup_eyeliner_01), colorMap.get("color_mu_style_eyeliner_01"),FaceParam.FACE_MAKEUP_TYPE_EYE_LINER));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_linear_drooping, getDrawable(R.mipmap.icon_makeup_eyeliner_02), colorMap.get("color_mu_style_eyeliner_02"),FaceParam.FACE_MAKEUP_TYPE_EYE_LINER));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_linear_pull_open, getDrawable(R.mipmap.icon_makeup_eyeliner_03), colorMap.get("color_mu_style_eyeliner_03"),FaceParam.FACE_MAKEUP_TYPE_EYE_LINER));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_linear_pull_close, getDrawable(R.mipmap.icon_makeup_eyeliner_04), colorMap.get("color_mu_style_eyeliner_04"),FaceParam.FACE_MAKEUP_TYPE_EYE_LINER));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_linear_long, getDrawable(R.mipmap.icon_makeup_eyeliner_05), colorMap.get("color_mu_style_eyeliner_05"),FaceParam.FACE_MAKEUP_TYPE_EYE_LINER));
|
||||
add(new MakeupCustomBean(R.string.makeup_eye_linear_circular, getDrawable(R.mipmap.icon_makeup_eyeliner_06), colorMap.get("color_mu_style_eyeliner_06"),FaceParam.FACE_MAKEUP_TYPE_EYE_LINER));
|
||||
}
|
||||
});
|
||||
/*睫毛*/
|
||||
mCustomItems.put(FACE_MAKEUP_TYPE_EYE_LASH, new ArrayList<MakeupCustomBean>() {
|
||||
{
|
||||
add(new MakeupCustomBean(R.string.makeup_radio_remove, getDrawable(R.mipmap.icon_control_none),FaceParam.FACE_MAKEUP_TYPE_EYE_LASH));
|
||||
add(new MakeupCustomBean(R.string.makeup_eyelash_natural1, getDrawable(R.mipmap.icon_makeup_eyelash_01), colorMap.get("color_mu_style_eyelash_01"),FaceParam.FACE_MAKEUP_TYPE_EYE_LASH));
|
||||
add(new MakeupCustomBean(R.string.makeup_eyelash_natural2, getDrawable(R.mipmap.icon_makeup_eyelash_02), colorMap.get("color_mu_style_eyelash_02"),FaceParam.FACE_MAKEUP_TYPE_EYE_LASH));
|
||||
add(new MakeupCustomBean(R.string.makeup_eyelash_thick1, getDrawable(R.mipmap.icon_makeup_eyelash_03), colorMap.get("color_mu_style_eyelash_03"),FaceParam.FACE_MAKEUP_TYPE_EYE_LASH));
|
||||
add(new MakeupCustomBean(R.string.makeup_eyelash_thick2, getDrawable(R.mipmap.icon_makeup_eyelash_04), colorMap.get("color_mu_style_eyelash_04"),FaceParam.FACE_MAKEUP_TYPE_EYE_LASH));
|
||||
add(new MakeupCustomBean(R.string.makeup_eyelash_exaggerate1, getDrawable(R.mipmap.icon_makeup_eyelash_05), colorMap.get("color_mu_style_eyelash_05"),FaceParam.FACE_MAKEUP_TYPE_EYE_LASH));
|
||||
add(new MakeupCustomBean(R.string.makeup_eyelash_exaggerate2, getDrawable(R.mipmap.icon_makeup_eyelash_06), colorMap.get("color_mu_style_eyelash_06"),FaceParam.FACE_MAKEUP_TYPE_EYE_LASH));
|
||||
}
|
||||
});
|
||||
|
||||
/*高光*/
|
||||
mCustomItems.put(FACE_MAKEUP_TYPE_HIGH_LIGHT, new ArrayList<MakeupCustomBean>() {
|
||||
{
|
||||
add(new MakeupCustomBean(R.string.makeup_radio_remove, getDrawable(R.mipmap.icon_control_none),FaceParam.FACE_MAKEUP_TYPE_HIGH_LIGHT));
|
||||
add(new MakeupCustomBean(R.string.makeup_highlight_one, getDrawable(R.mipmap.icon_makeup_highlight_01), colorMap.get("color_mu_style_highlight_01"),FaceParam.FACE_MAKEUP_TYPE_HIGH_LIGHT));
|
||||
add(new MakeupCustomBean(R.string.makeup_highlight_two, getDrawable(R.mipmap.icon_makeup_highlight_02), colorMap.get("color_mu_style_highlight_02"),FaceParam.FACE_MAKEUP_TYPE_HIGH_LIGHT));
|
||||
}
|
||||
});
|
||||
/*阴影*/
|
||||
mCustomItems.put(FACE_MAKEUP_TYPE_SHADOW, new ArrayList<MakeupCustomBean>() {
|
||||
{
|
||||
add(new MakeupCustomBean(R.string.makeup_radio_remove, getDrawable(R.mipmap.icon_control_none),FaceParam.FACE_MAKEUP_TYPE_SHADOW));
|
||||
add(new MakeupCustomBean(R.string.makeup_shadow_one, getDrawable(R.mipmap.icon_makeup_contour_01), colorMap.get("color_mu_style_contour_01"),FaceParam.FACE_MAKEUP_TYPE_SHADOW));
|
||||
}
|
||||
});
|
||||
/*美瞳*/
|
||||
mCustomItems.put(FACE_MAKEUP_TYPE_EYE_PUPIL, new ArrayList<MakeupCustomBean>() {
|
||||
{
|
||||
add(new MakeupCustomBean(R.string.makeup_radio_remove, getDrawable(R.mipmap.icon_control_none),FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
add(new MakeupCustomBean(R.string.makeup_pupil_1, getDrawable(R.mipmap.icon_makeup_eyepupil_01), colorMap.get("color_mu_style_eyepupil_01"),FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
add(new MakeupCustomBean(R.string.makeup_pupil_2, getDrawable(R.mipmap.icon_makeup_eyepupil_03), null,FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
add(new MakeupCustomBean(R.string.makeup_pupil_3, getDrawable(R.mipmap.icon_makeup_eyepupil_04), null,FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
add(new MakeupCustomBean(R.string.makeup_pupil_4, getDrawable(R.mipmap.icon_makeup_eyepupil_05), null,FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
add(new MakeupCustomBean(R.string.makeup_pupil_5, getDrawable(R.mipmap.icon_makeup_eyepupil_06), null,FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
add(new MakeupCustomBean(R.string.makeup_pupil_6, getDrawable(R.mipmap.icon_makeup_eyepupil_07), null,FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
add(new MakeupCustomBean(R.string.makeup_pupil_7, getDrawable(R.mipmap.icon_makeup_eyepupil_08), null,FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
add(new MakeupCustomBean(R.string.makeup_pupil_8, getDrawable(R.mipmap.icon_makeup_eyepupil_09), null,FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
}
|
||||
});
|
||||
return mCustomItems;
|
||||
}
|
||||
|
||||
|
||||
//endregion 子妆容
|
||||
|
||||
|
||||
//region 其他
|
||||
|
||||
/**
|
||||
* 获取颜色值配置
|
||||
*
|
||||
* @return LinkedHashMap<String, ArrayList < DoubleArray>>
|
||||
*/
|
||||
public static LinkedHashMap<String, ArrayList<double[]>> buildMakeUpColorMap() {
|
||||
LinkedHashMap<String, ArrayList<double[]>> makeupColorMap = new LinkedHashMap<>(32);
|
||||
String colorJson = FileUtils.INSTANCE.loadStringFromLocal(FaceUnityData.mApplication, FaceUnityConfig.MAKEUP_RESOURCE_COLOR_SETUP_JSON);
|
||||
if (colorJson != null && colorJson.trim().length() > 0) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(colorJson);
|
||||
Iterator<String> keys = jsonObject.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
ArrayList<double[]> colorList = new ArrayList(12);
|
||||
// add additional transparent to fit ui
|
||||
//增加透明色,兼容ColorRecycleView展示
|
||||
colorList.add(new double[]{0.0, 0.0, 0.0, 0.0});
|
||||
colorList.add(new double[]{0.0, 0.0, 0.0, 0.0});
|
||||
colorList.add(new double[]{0.0, 0.0, 0.0, 0.0});
|
||||
JSONObject colorObject = jsonObject.optJSONObject(key);
|
||||
for (int i = 1; i < 6; i++) {
|
||||
JSONArray jsonArray = colorObject.optJSONArray("color" + i);
|
||||
int length = jsonArray.length();
|
||||
double[] colors = new double[length];
|
||||
for (int j = 0; j < length; j++) {
|
||||
colors[j] = jsonArray.optDouble(j, 0.0);
|
||||
}
|
||||
colorList.add(colors);
|
||||
}
|
||||
colorList.add(new double[]{0.0, 0.0, 0.0, 0.0});
|
||||
colorList.add(new double[]{0.0, 0.0, 0.0, 0.0});
|
||||
colorList.add(new double[]{0.0, 0.0, 0.0, 0.0});
|
||||
makeupColorMap.put(key, colorList);
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
return makeupColorMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取Drawable对象
|
||||
*
|
||||
* @param res Int
|
||||
* @return Drawable
|
||||
*/
|
||||
@SuppressLint("UseCompatLoadingForDrawables")
|
||||
private static Drawable getDrawable(int res) {
|
||||
return FaceUnityData.mApplication.getResources().getDrawable(res);
|
||||
}
|
||||
//endregion
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.yunbao.faceunity.repo;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.entity.FUColorRGBData;
|
||||
import com.faceunity.core.model.prop.humanOutline.HumanOutline;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.entity.FunctionEnum;
|
||||
import com.yunbao.faceunity.entity.PropCustomBean;
|
||||
import com.yunbao.faceunity.infe.AbstractPropCustomDataFactory;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
import com.yunbao.faceunity.utils.FaceUnityData;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DESC:人像分割数据构造
|
||||
* Created on 2021/3/28
|
||||
*/
|
||||
public class PortraitSegmentSource {
|
||||
|
||||
private static final String BG_SEG_CUSTOM_FILEPATH = "bg_seg_custom";
|
||||
|
||||
/**
|
||||
* 缓存自定义添加人像
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
public static void saveCachePortraitSegment(String path) {
|
||||
SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(BG_SEG_CUSTOM_FILEPATH, MODE_PRIVATE);
|
||||
sp.edit().putString(BG_SEG_CUSTOM_FILEPATH, path).apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自定义添加人像
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getCachePortraitSegment() {
|
||||
SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(BG_SEG_CUSTOM_FILEPATH, MODE_PRIVATE);
|
||||
return sp.getString(BG_SEG_CUSTOM_FILEPATH, "");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造道具队列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<PropCustomBean> buildPropBeans() {
|
||||
ArrayList<PropCustomBean> propBeans = new ArrayList<>();
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_control_delete_all, null, AbstractPropCustomDataFactory.TYPE_NONE));
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_control_add, null, AbstractPropCustomDataFactory.TYPE_ADD));
|
||||
PropCustomBean customBean = buildPropCustomBean(getCachePortraitSegment());
|
||||
if (customBean != null) {
|
||||
propBeans.add(customBean);
|
||||
}
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_segment_human_outline, "effect/segment/human_outline.bundle", FunctionEnum.HUMAN_OUTLINE));
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_segment_boyfriend_1, "effect/segment/boyfriend1.bundle", FunctionEnum.PORTRAIT_SEGMENT));
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_segment_boyfriend_2, "effect/segment/boyfriend3.bundle", FunctionEnum.PORTRAIT_SEGMENT));
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_segment_boyfriend_3, "effect/segment/boyfriend2.bundle", FunctionEnum.PORTRAIT_SEGMENT));
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_segment_hez_ztt_fu, "effect/segment/hez_ztt_fu.bundle", FunctionEnum.PORTRAIT_SEGMENT, R.string.hez_ztt_fu));
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_segment_gufeng_zh_fu, "effect/segment/gufeng_zh_fu.bundle", FunctionEnum.PORTRAIT_SEGMENT));
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_segment_xiandai_ztt_fu, "effect/segment/xiandai_ztt_fu.bundle", FunctionEnum.PORTRAIT_SEGMENT));
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_segment_sea_lm_fu, "effect/segment/sea_lm_fu.bundle", FunctionEnum.PORTRAIT_SEGMENT));
|
||||
propBeans.add(new PropCustomBean(R.mipmap.icon_segment_ice_lm_fu, "effect/segment/ice_lm_fu.bundle", FunctionEnum.PORTRAIT_SEGMENT));
|
||||
return propBeans;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造自定义人像分割
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
public static PropCustomBean buildPropCustomBean(String path) {
|
||||
if (path != null && path.trim().length() > 0 && new File(path).exists()) {
|
||||
saveCachePortraitSegment(path);
|
||||
return new PropCustomBean(0, FaceUnityConfig.BUNDLE_BG_SEG_CUSTOM, FunctionEnum.BG_SEG_CUSTOM, 0, path );
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造人像分割线模型
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
public static HumanOutline getHumanOutline(String path) {
|
||||
HumanOutline humanOutline = new HumanOutline(new FUBundleData(path));
|
||||
humanOutline.setLineSize(2.8);
|
||||
humanOutline.setLineGap(2.8);
|
||||
humanOutline.setLineColor(new FUColorRGBData(255.0, 196.0, 0.0));
|
||||
return humanOutline;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.yunbao.faceunity.repo;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
import com.yunbao.faceunity.entity.FunctionEnum;
|
||||
import com.yunbao.faceunity.entity.PropBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DESC:道具数据构造:道具贴图、AR面具、搞笑大头、表情识别、哈哈镜、手势识别、游戏
|
||||
* Created on 2021/3/28
|
||||
*/
|
||||
public class PropSource {
|
||||
|
||||
public static ArrayList<PropBean> buildPropBeans(int propType) {
|
||||
ArrayList<PropBean> propBeans = new ArrayList<>();
|
||||
switch (propType) {
|
||||
case FunctionEnum.STICKER:
|
||||
propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null, FaceParam.FACE_STICKER));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_sticker_cat_sparks, "effect/normal/cat_sparks.bundle", FaceParam.FACE_STICKER));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_sticker_fu_zh_fenshu, "effect/normal/fu_zh_fenshu.bundle", FaceParam.FACE_STICKER));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_sticker_sdlr, "effect/normal/sdlr.bundle", FaceParam.FACE_STICKER));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_sticker_xlong_zh_fu, "effect/normal/xlong_zh_fu.bundle", FaceParam.FACE_STICKER));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_sticker_newy1, "effect/normal/newy1.bundle", FaceParam.FACE_STICKER));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_sticker_redribbt, "effect/normal/redribbt.bundle", FaceParam.FACE_STICKER));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_sticker_daisypig, "effect/normal/daisypig.bundle", FaceParam.FACE_STICKER));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_sticker_sdlu, "effect/normal/sdlu.bundle", FaceParam.FACE_STICKER));
|
||||
break;
|
||||
case FunctionEnum.AR_MASK:
|
||||
propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null, FaceParam.FACE_ANIM_AR_MASK));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_ar_bluebird, "effect/ar/bluebird.bundle", FaceParam.FACE_ANIM_AR_MASK));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_ar_lanhudie, "effect/ar/lanhudie.bundle", FaceParam.FACE_ANIM_AR_MASK));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_ar_fenhudie, "effect/ar/fenhudie.bundle", FaceParam.FACE_ANIM_AR_MASK));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_ar_tiger_huang, "effect/ar/tiger_huang.bundle", FaceParam.FACE_ANIM_AR_MASK));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_ar_tiger_bai, "effect/ar/tiger_bai.bundle", FaceParam.FACE_ANIM_AR_MASK));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_ar_baozi, "effect/ar/baozi.bundle", FaceParam.FACE_ANIM_AR_MASK));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_ar_tiger, "effect/ar/tiger.bundle", FaceParam.FACE_ANIM_AR_MASK));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_ar_xiongmao, "effect/ar/xiongmao.bundle", FaceParam.FACE_ANIM_AR_MASK));
|
||||
break;
|
||||
case FunctionEnum.BIG_HEAD:
|
||||
propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null, FaceParam.FACE_BIG_HEAD));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_big_head, "effect/big_head/big_head.bundle", FaceParam.FACE_BIG_HEAD));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_big_head_husky_face, "effect/big_head/big_head_facewarp2.bundle", FaceParam.FACE_BIG_HEAD));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_big_head_sausage_mouth, "effect/big_head/big_head_facewarp4.bundle", FaceParam.FACE_BIG_HEAD));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_big_head_blush, "effect/big_head/big_head_facewarp5.bundle", FaceParam.FACE_BIG_HEAD));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_big_head_dark_circles, "effect/big_head/big_head_facewarp6.bundle", FaceParam.FACE_BIG_HEAD));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_big_head_smiling_head, "effect/big_head/big_head_smile.bundle", R.string.xiaobianzi_zh_fu, FaceParam.FACE_BIG_HEAD));
|
||||
break;
|
||||
case FunctionEnum.EXPRESSION_RECOGNITION:
|
||||
propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null,FaceParam.FACE_EXPRESSION_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_expression_future_warrior, "effect/expression/future_warrior.bundle", R.string.future_warrior,FaceParam.FACE_EXPRESSION_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_expression_jet_mask, "effect/expression/jet_mask.bundle", R.string.jet_mask,FaceParam.FACE_EXPRESSION_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_expression_sdx2, "effect/expression/sdx2.bundle", R.string.sdx2,FaceParam.FACE_EXPRESSION_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_expression_luhantongkuan_ztt_fu, "effect/expression/luhantongkuan_ztt_fu.bundle", R.string.luhantongkuan_ztt_fu,FaceParam.FACE_EXPRESSION_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_expression_qingqing_ztt_fu, "effect/expression/qingqing_ztt_fu.bundle", R.string.qingqing_ztt_fu,FaceParam.FACE_EXPRESSION_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_expression_xiaobianzi_zh_fu, "effect/expression/xiaobianzi_zh_fu.bundle", R.string.xiaobianzi_zh_fu,FaceParam.FACE_EXPRESSION_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_expression_xiaoxueshen_ztt_fu, "effect/expression/xiaoxueshen_ztt_fu.bundle", R.string.xiaoxueshen_ztt_fu,FaceParam.FACE_EXPRESSION_RECOGNITION));
|
||||
break;
|
||||
case FunctionEnum.FACE_WARP:
|
||||
propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null,FaceParam.FACE_FACE_WARP));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_face_warp_2, "effect/facewarp/facewarp2.bundle",FaceParam.FACE_FACE_WARP));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_face_warp_3, "effect/facewarp/facewarp3.bundle",FaceParam.FACE_FACE_WARP));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_face_warp_4, "effect/facewarp/facewarp4.bundle",FaceParam.FACE_FACE_WARP));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_face_warp_5, "effect/facewarp/facewarp5.bundle",FaceParam.FACE_FACE_WARP));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_face_warp_6, "effect/facewarp/facewarp6.bundle",FaceParam.FACE_FACE_WARP));
|
||||
break;
|
||||
case FunctionEnum.GESTURE_RECOGNITION:
|
||||
propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null,FaceParam.FACE_GESTURE_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_gesture_rain, "effect/gesture/ctrl_rain.bundle", R.string.push_hand,FaceParam.FACE_GESTURE_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_gesture_snow, "effect/gesture/ctrl_snow.bundle", R.string.push_hand,FaceParam.FACE_GESTURE_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_gesture_flower, "effect/gesture/ctrl_flower.bundle", R.string.push_hand,FaceParam.FACE_GESTURE_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_gesture_koreaheart, "effect/gesture/ssd_thread_korheart.bundle", R.string.fu_lm_koreaheart,FaceParam.FACE_GESTURE_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_gesture_six, "effect/gesture/ssd_thread_six.bundle", R.string.ssd_thread_six,FaceParam.FACE_GESTURE_RECOGNITION));
|
||||
propBeans.add(new PropBean(R.mipmap.icon_gesture_cute, "effect/gesture/ssd_thread_cute.bundle", R.string.ssd_thread_cute,FaceParam.FACE_GESTURE_RECOGNITION));
|
||||
break;
|
||||
}
|
||||
return propBeans;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,196 @@
|
||||
package com.yunbao.faceunity.seekbar.internal;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.seekbar.internal.compat.SeekBarCompat;
|
||||
import com.yunbao.faceunity.seekbar.internal.drawable.MarkerDrawable;
|
||||
|
||||
|
||||
/**
|
||||
* {@link ViewGroup} to be used as the real indicator.
|
||||
* <p>
|
||||
* I've used this to be able to accommodate the TextView
|
||||
* and the {@link MarkerDrawable}
|
||||
* with the required positions and offsets
|
||||
* </p>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class Marker extends ViewGroup implements MarkerDrawable.MarkerAnimationListener {
|
||||
private static final int PADDING_DP = 1;
|
||||
private static final int ELEVATION_DP = 8;
|
||||
//The TextView to show the info
|
||||
private TextView mNumber;
|
||||
//The max width of this View
|
||||
private int mWidth;
|
||||
//some distance between the thumb and our bubble marker.
|
||||
//This will be added to our measured height
|
||||
private int mSeparation;
|
||||
MarkerDrawable mMarkerDrawable;
|
||||
|
||||
public Marker(Context context, AttributeSet attrs, int defStyleAttr, String maxValue, int thumbSize, int separation) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
//as we're reading the parent DiscreteSeekBar attributes, it may wrongly set this view's visibility.
|
||||
setVisibility(View.VISIBLE);
|
||||
|
||||
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DiscreteSeekBar,
|
||||
R.attr.discreteSeekBarStyle, R.style.Widget_DiscreteSeekBar);
|
||||
|
||||
int padding = (int) (PADDING_DP * displayMetrics.density) * 2;
|
||||
int textAppearanceId = a.getResourceId(R.styleable.DiscreteSeekBar_dsb_indicatorTextAppearance,
|
||||
R.style.Widget_DiscreteIndicatorTextAppearance);
|
||||
mNumber = new TextView(context);
|
||||
//Add some padding to this textView so the bubble has some space to breath
|
||||
mNumber.setPadding(padding, 0, padding, 0);
|
||||
mNumber.setTextAppearance(context, textAppearanceId);
|
||||
mNumber.setGravity(Gravity.CENTER);
|
||||
mNumber.setText(maxValue);
|
||||
mNumber.setMaxLines(1);
|
||||
mNumber.setSingleLine(true);
|
||||
SeekBarCompat.setTextDirection(mNumber, TEXT_DIRECTION_LOCALE);
|
||||
mNumber.setVisibility(View.INVISIBLE);
|
||||
|
||||
//add some padding for the elevation shadow not to be clipped
|
||||
//I'm sure there are better ways of doing this...
|
||||
setPadding(padding, padding, padding, padding);
|
||||
|
||||
resetSizes(maxValue);
|
||||
|
||||
mSeparation = separation;
|
||||
ColorStateList color = a.getColorStateList(R.styleable.DiscreteSeekBar_dsb_indicatorColor);
|
||||
mMarkerDrawable = new MarkerDrawable(color, thumbSize);
|
||||
mMarkerDrawable.setCallback(this);
|
||||
mMarkerDrawable.setMarkerListener(this);
|
||||
mMarkerDrawable.setExternalOffset(padding);
|
||||
|
||||
//Elevation for anroid 5+
|
||||
float elevation = a.getDimension(R.styleable.DiscreteSeekBar_dsb_indicatorElevation, ELEVATION_DP * displayMetrics.density);
|
||||
ViewCompat.setElevation(this, elevation);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
SeekBarCompat.setOutlineProvider(this, mMarkerDrawable);
|
||||
}
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
public void resetSizes(String maxValue) {
|
||||
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
|
||||
//Account for negative numbers... is there any proper way of getting the biggest string between our range????
|
||||
mNumber.setText("-" + maxValue);
|
||||
//Do a first forced measure call for the TextView (with the biggest text content),
|
||||
//to calculate the max width and use always the same.
|
||||
//this avoids the TextView from shrinking and growing when the text content changes
|
||||
int wSpec = MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels, MeasureSpec.AT_MOST);
|
||||
int hSpec = MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels, MeasureSpec.AT_MOST);
|
||||
mNumber.measure(wSpec, hSpec);
|
||||
mWidth = Math.max(mNumber.getMeasuredWidth(), mNumber.getMeasuredHeight());
|
||||
removeView(mNumber);
|
||||
addView(mNumber, new FrameLayout.LayoutParams(mWidth, mWidth, Gravity.LEFT | Gravity.TOP));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
mMarkerDrawable.draw(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
measureChildren(widthMeasureSpec, heightMeasureSpec);
|
||||
int widthSize = mWidth + getPaddingLeft() + getPaddingRight();
|
||||
int heightSize = mWidth + getPaddingTop() + getPaddingBottom();
|
||||
//This diff is the basic calculation of the difference between
|
||||
//a square side size and its diagonal
|
||||
//this helps us account for the visual offset created by MarkerDrawable
|
||||
//when leaving one of the corners un-rounded
|
||||
int diff = (int) ((1.41f * mWidth) - mWidth) / 2;
|
||||
setMeasuredDimension(widthSize, heightSize + diff + mSeparation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
int left = getPaddingLeft();
|
||||
int top = getPaddingTop();
|
||||
int right = getWidth() - getPaddingRight();
|
||||
int bottom = getHeight() - getPaddingBottom();
|
||||
//the TetView is always layout at the top
|
||||
mNumber.layout(left, top, left + mWidth, top + mWidth);
|
||||
//the MarkerDrawable uses the whole view, it will adapt itself...
|
||||
// or it seems so...
|
||||
mMarkerDrawable.setBounds(left, top, right, bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean verifyDrawable(Drawable who) {
|
||||
return who == mMarkerDrawable || super.verifyDrawable(who);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
//HACK: Sometimes, the animateOpen() call is made before the View is attached
|
||||
//so the drawable cannot schedule itself to run the animation
|
||||
//I think we can call it here safely.
|
||||
//I've seen it happen in android 2.3.7
|
||||
animateOpen();
|
||||
}
|
||||
|
||||
public void setValue(CharSequence value) {
|
||||
mNumber.setText(value);
|
||||
}
|
||||
|
||||
public CharSequence getValue() {
|
||||
return mNumber.getText();
|
||||
}
|
||||
|
||||
public void animateOpen() {
|
||||
mMarkerDrawable.stop();
|
||||
mMarkerDrawable.animateToPressed();
|
||||
}
|
||||
|
||||
public void animateClose() {
|
||||
mMarkerDrawable.stop();
|
||||
mNumber.setVisibility(View.INVISIBLE);
|
||||
mMarkerDrawable.animateToNormal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpeningComplete() {
|
||||
mNumber.setVisibility(View.VISIBLE);
|
||||
if (getParent() instanceof MarkerDrawable.MarkerAnimationListener) {
|
||||
((MarkerDrawable.MarkerAnimationListener) getParent()).onOpeningComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosingComplete() {
|
||||
if (getParent() instanceof MarkerDrawable.MarkerAnimationListener) {
|
||||
((MarkerDrawable.MarkerAnimationListener) getParent()).onClosingComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mMarkerDrawable.stop();
|
||||
}
|
||||
|
||||
public void setColors(int startColor, int endColor) {
|
||||
mMarkerDrawable.setColors(startColor, endColor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
package com.yunbao.faceunity.seekbar.internal;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.core.view.GravityCompat;
|
||||
|
||||
import com.yunbao.faceunity.seekbar.internal.compat.SeekBarCompat;
|
||||
import com.yunbao.faceunity.seekbar.internal.drawable.MarkerDrawable;
|
||||
|
||||
|
||||
/**
|
||||
* Class to manage the floating bubble thing, similar (but quite worse tested than {@link android.widget.PopupWindow}
|
||||
* <p/>
|
||||
* <p>
|
||||
* This will attach a View to the Window (full-width, measured-height, positioned just under the thumb)
|
||||
* </p>
|
||||
*
|
||||
* @hide
|
||||
* @see #showIndicator(View, Rect)
|
||||
* @see #dismiss()
|
||||
* @see #dismissComplete()
|
||||
* @see Floater
|
||||
*/
|
||||
public class PopupIndicator {
|
||||
|
||||
private final WindowManager mWindowManager;
|
||||
private boolean mShowing;
|
||||
private Floater mPopupView;
|
||||
//Outside listener for the DiscreteSeekBar to get MarkerDrawable animation events.
|
||||
//The whole chain of events goes this way:
|
||||
//MarkerDrawable->Marker->Floater->mListener->DiscreteSeekBar....
|
||||
//... phew!
|
||||
private MarkerDrawable.MarkerAnimationListener mListener;
|
||||
private int[] mDrawingLocation = new int[2];
|
||||
Point screenSize = new Point();
|
||||
|
||||
public PopupIndicator(Context context, AttributeSet attrs, int defStyleAttr, String maxValue, int thumbSize, int separation) {
|
||||
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
mPopupView = new Floater(context, attrs, defStyleAttr, maxValue, thumbSize, separation);
|
||||
}
|
||||
|
||||
public void updateSizes(String maxValue) {
|
||||
dismissComplete();
|
||||
if (mPopupView != null) {
|
||||
mPopupView.mMarker.resetSizes(maxValue);
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener(MarkerDrawable.MarkerAnimationListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* We want the Floater to be full-width because the contents will be moved from side to side.
|
||||
* We may/should change this in the future to use just the PARENT View width and/or pass it in the constructor
|
||||
*/
|
||||
private void measureFloater() {
|
||||
int specWidth = View.MeasureSpec.makeMeasureSpec(screenSize.x, View.MeasureSpec.EXACTLY);
|
||||
int specHeight = View.MeasureSpec.makeMeasureSpec(screenSize.y, View.MeasureSpec.AT_MOST);
|
||||
mPopupView.measure(specWidth, specHeight);
|
||||
}
|
||||
|
||||
public void setValue(CharSequence value) {
|
||||
mPopupView.mMarker.setValue(value);
|
||||
}
|
||||
|
||||
public boolean isShowing() {
|
||||
return mShowing;
|
||||
}
|
||||
|
||||
public void showIndicator(View parent, Rect touchBounds) {
|
||||
if (isShowing()) {
|
||||
mPopupView.mMarker.animateOpen();
|
||||
return;
|
||||
}
|
||||
|
||||
IBinder windowToken = parent.getWindowToken();
|
||||
if (windowToken != null) {
|
||||
WindowManager.LayoutParams p = createPopupLayout(windowToken);
|
||||
|
||||
p.gravity = Gravity.TOP | GravityCompat.START;
|
||||
updateLayoutParamsForPosiion(parent, p, touchBounds.bottom);
|
||||
mShowing = true;
|
||||
|
||||
translateViewIntoPosition(touchBounds.centerX());
|
||||
invokePopup(p);
|
||||
}
|
||||
}
|
||||
|
||||
public void move(int x) {
|
||||
if (!isShowing()) {
|
||||
return;
|
||||
}
|
||||
translateViewIntoPosition(x);
|
||||
}
|
||||
|
||||
public void setColors(int startColor, int endColor) {
|
||||
mPopupView.setColors(startColor, endColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will start the closing animation of the Marker and call onClosingComplete when finished
|
||||
*/
|
||||
public void dismiss() {
|
||||
mPopupView.mMarker.animateClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* FORCE the popup window to be removed.
|
||||
* You typically calls this when the parent view is being removed from the window to avoid a Window Leak
|
||||
*/
|
||||
public void dismissComplete() {
|
||||
if (isShowing()) {
|
||||
mShowing = false;
|
||||
try {
|
||||
mWindowManager.removeViewImmediate(mPopupView);
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateLayoutParamsForPosiion(View anchor, WindowManager.LayoutParams p, int yOffset) {
|
||||
DisplayMetrics displayMetrics = anchor.getResources().getDisplayMetrics();
|
||||
screenSize.set(displayMetrics.widthPixels, displayMetrics.heightPixels);
|
||||
|
||||
measureFloater();
|
||||
int measuredHeight = mPopupView.getMeasuredHeight();
|
||||
int paddingBottom = mPopupView.mMarker.getPaddingBottom();
|
||||
anchor.getLocationInWindow(mDrawingLocation);
|
||||
p.x = 0;
|
||||
p.y = mDrawingLocation[1] - measuredHeight + yOffset + paddingBottom;
|
||||
p.width = screenSize.x;
|
||||
p.height = measuredHeight;
|
||||
}
|
||||
|
||||
private void translateViewIntoPosition(final int x) {
|
||||
mPopupView.setFloatOffset(x + mDrawingLocation[0]);
|
||||
}
|
||||
|
||||
private void invokePopup(WindowManager.LayoutParams p) {
|
||||
mWindowManager.addView(mPopupView, p);
|
||||
mPopupView.mMarker.animateOpen();
|
||||
}
|
||||
|
||||
private WindowManager.LayoutParams createPopupLayout(IBinder token) {
|
||||
WindowManager.LayoutParams p = new WindowManager.LayoutParams();
|
||||
p.gravity = Gravity.START | Gravity.TOP;
|
||||
p.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
p.height = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
p.format = PixelFormat.TRANSLUCENT;
|
||||
p.flags = computeFlags(p.flags);
|
||||
p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
|
||||
p.token = token;
|
||||
p.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN;
|
||||
p.setTitle("DiscreteSeekBar Indicator:" + Integer.toHexString(hashCode()));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* I'm NOT completely sure how all this bitwise things work...
|
||||
*
|
||||
* @param curFlags
|
||||
* @return
|
||||
*/
|
||||
private int computeFlags(int curFlags) {
|
||||
curFlags &= ~(
|
||||
WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES |
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
|
||||
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
|
||||
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
|
||||
curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
|
||||
curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
||||
curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
|
||||
return curFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Small FrameLayout class to hold and move the bubble around when requested
|
||||
* I wanted to use the {@link Marker} directly
|
||||
* but doing so would make some things harder to implement
|
||||
* (like moving the marker around, having the Marker's outline to work, etc)
|
||||
*/
|
||||
private class Floater extends FrameLayout implements MarkerDrawable.MarkerAnimationListener {
|
||||
private Marker mMarker;
|
||||
private int mOffset;
|
||||
|
||||
public Floater(Context context, AttributeSet attrs, int defStyleAttr, String maxValue, int thumbSize, int separation) {
|
||||
super(context);
|
||||
mMarker = new Marker(context, attrs, defStyleAttr, maxValue, thumbSize, separation);
|
||||
addView(mMarker, new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
measureChildren(widthMeasureSpec, heightMeasureSpec);
|
||||
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int heightSie = mMarker.getMeasuredHeight();
|
||||
setMeasuredDimension(widthSize, heightSie);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
int centerDiffX = mMarker.getMeasuredWidth() / 2;
|
||||
int offset = (mOffset - centerDiffX);
|
||||
mMarker.layout(offset, 0, offset + mMarker.getMeasuredWidth(), mMarker.getMeasuredHeight());
|
||||
}
|
||||
|
||||
public void setFloatOffset(int x) {
|
||||
mOffset = x;
|
||||
int centerDiffX = mMarker.getMeasuredWidth() / 2;
|
||||
int offset = (x - centerDiffX);
|
||||
mMarker.offsetLeftAndRight(offset - mMarker.getLeft());
|
||||
//Without hardware acceleration (or API levels<11), offsetting a view seems to NOT invalidate the proper area.
|
||||
//We should calc the proper invalidate Rect but this will be for now...
|
||||
if (!SeekBarCompat.isHardwareAccelerated(this)) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosingComplete() {
|
||||
if (mListener != null) {
|
||||
mListener.onClosingComplete();
|
||||
}
|
||||
dismissComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpeningComplete() {
|
||||
if (mListener != null) {
|
||||
mListener.onOpeningComplete();
|
||||
}
|
||||
}
|
||||
|
||||
public void setColors(int startColor, int endColor) {
|
||||
mMarker.setColors(startColor, endColor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.yunbao.faceunity.seekbar.internal.compat;
|
||||
|
||||
|
||||
import com.yunbao.faceunity.seekbar.DiscreteSeekBar;
|
||||
|
||||
/**
|
||||
* Currently, there's no {@link android.animation.ValueAnimator} compatibility version
|
||||
* and as we didn't want to throw in external dependencies, we made this small class.
|
||||
* <p/>
|
||||
* <p>
|
||||
* This will work like {@link android.support.v4.view.ViewPropertyAnimatorCompat}, that is,
|
||||
* not doing anything on API<11 and using the default {@link android.animation.ValueAnimator}
|
||||
* on API>=11
|
||||
* </p>
|
||||
* <p>
|
||||
* This class is used to provide animation to the {@link DiscreteSeekBar}
|
||||
* when navigating with the Keypad
|
||||
* </p>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract class AnimatorCompat {
|
||||
public interface AnimationFrameUpdateListener {
|
||||
public void onAnimationFrame(float currentValue);
|
||||
}
|
||||
|
||||
AnimatorCompat() {
|
||||
|
||||
}
|
||||
|
||||
public abstract void cancel();
|
||||
|
||||
public abstract boolean isRunning();
|
||||
|
||||
public abstract void setDuration(int progressAnimationDuration);
|
||||
|
||||
public abstract void start();
|
||||
|
||||
public static final AnimatorCompat create(float start, float end, AnimationFrameUpdateListener listener) {
|
||||
return new AnimatorCompatBase(start, end, listener);
|
||||
}
|
||||
|
||||
private static class AnimatorCompatBase extends AnimatorCompat {
|
||||
|
||||
private final AnimationFrameUpdateListener mListener;
|
||||
private final float mEndValue;
|
||||
|
||||
public AnimatorCompatBase(float start, float end, AnimationFrameUpdateListener listener) {
|
||||
mListener = listener;
|
||||
mEndValue = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDuration(int progressAnimationDuration) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
mListener.onAnimationFrame(mEndValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.yunbao.faceunity.seekbar.internal.compat;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
|
||||
import com.yunbao.faceunity.seekbar.internal.drawable.AlmostRippleDrawable;
|
||||
import com.yunbao.faceunity.seekbar.internal.drawable.MarkerDrawable;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper compatibility class to call some API-Specific methods
|
||||
* And offer alternate procedures when possible
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class SeekBarCompat {
|
||||
|
||||
/**
|
||||
* Sets the custom Outline provider on API>=21.
|
||||
* Does nothing on API<21
|
||||
*
|
||||
* @param view
|
||||
* @param markerDrawable
|
||||
*/
|
||||
public static void setOutlineProvider(View view, final MarkerDrawable markerDrawable) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
SeekBarCompatDontCrash.setOutlineProvider(view, markerDrawable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Our DiscreteSeekBar implementation uses a circular drawable on API < 21
|
||||
* because we don't set it as Background, but draw it ourselves
|
||||
*
|
||||
* @param colorStateList
|
||||
* @return
|
||||
*/
|
||||
public static Drawable getRipple(ColorStateList colorStateList) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
return SeekBarCompatDontCrash.getRipple(colorStateList);
|
||||
} else {
|
||||
return new AlmostRippleDrawable(colorStateList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of the seekbar ripple
|
||||
*
|
||||
* @param drawable
|
||||
* @param colorStateList The ColorStateList the track ripple will be changed to
|
||||
*/
|
||||
public static void setRippleColor(@NonNull Drawable drawable, ColorStateList colorStateList) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
((RippleDrawable) drawable).setColor(colorStateList);
|
||||
} else {
|
||||
((AlmostRippleDrawable) drawable).setColor(colorStateList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* As our DiscreteSeekBar implementation uses a circular drawable on API < 21
|
||||
* we want to use the same method to set its bounds as the Ripple's hotspot bounds.
|
||||
*
|
||||
* @param drawable
|
||||
* @param left
|
||||
* @param top
|
||||
* @param right
|
||||
* @param bottom
|
||||
*/
|
||||
public static void setHotspotBounds(Drawable drawable, int left, int top, int right, int bottom) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
//We don't want the full size rect, Lollipop ripple would be too big
|
||||
int size = (right - left) / 8;
|
||||
DrawableCompat.setHotspotBounds(drawable, left + size, top + size, right - size, bottom - size);
|
||||
} else {
|
||||
drawable.setBounds(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* android.support.v4.view.ViewCompat SHOULD include this once and for all!!
|
||||
* But it doesn't...
|
||||
*
|
||||
* @param view
|
||||
* @param background
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setBackground(View view, Drawable background) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
SeekBarCompatDontCrash.setBackground(view, background);
|
||||
} else {
|
||||
view.setBackgroundDrawable(background);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the TextView text direction attribute when possible
|
||||
*
|
||||
* @param textView
|
||||
* @param textDirection
|
||||
* @see TextView#setTextDirection(int)
|
||||
*/
|
||||
public static void setTextDirection(TextView textView, int textDirection) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
SeekBarCompatDontCrash.setTextDirection(textView, textDirection);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isInScrollingContainer(ViewParent p) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
return SeekBarCompatDontCrash.isInScrollingContainer(p);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isHardwareAccelerated(View view) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
return SeekBarCompatDontCrash.isHardwareAccelerated(view);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.yunbao.faceunity.seekbar.internal.compat;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.yunbao.faceunity.seekbar.internal.drawable.MarkerDrawable;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper compatibility class to call some API-Specific methods
|
||||
* And offer alternate procedures when possible
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TargetApi(21)
|
||||
class SeekBarCompatDontCrash {
|
||||
public static void setOutlineProvider(View marker, final MarkerDrawable markerDrawable) {
|
||||
marker.setOutlineProvider(new ViewOutlineProvider() {
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline) {
|
||||
outline.setConvexPath(markerDrawable.getPath());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Drawable getRipple(ColorStateList colorStateList) {
|
||||
return new RippleDrawable(colorStateList, null, null);
|
||||
}
|
||||
|
||||
public static void setBackground(View view, Drawable background) {
|
||||
view.setBackground(background);
|
||||
}
|
||||
|
||||
public static void setTextDirection(TextView number, int textDirection) {
|
||||
number.setTextDirection(textDirection);
|
||||
}
|
||||
|
||||
public static boolean isInScrollingContainer(ViewParent p) {
|
||||
while (p != null && p instanceof ViewGroup) {
|
||||
if (((ViewGroup) p).shouldDelayChildPressedState()) {
|
||||
return true;
|
||||
}
|
||||
p = p.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isHardwareAccelerated(View view) {
|
||||
return view.isHardwareAccelerated();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
package com.yunbao.faceunity.seekbar.internal.drawable;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.os.SystemClock;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
||||
public class AlmostRippleDrawable extends StateDrawable implements Animatable {
|
||||
private static final long FRAME_DURATION = 1000 / 60;
|
||||
private static final int ANIMATION_DURATION = 250;
|
||||
|
||||
private static final float INACTIVE_SCALE = 0f;
|
||||
private static final float ACTIVE_SCALE = 1f;
|
||||
private float mCurrentScale = INACTIVE_SCALE;
|
||||
private Interpolator mInterpolator;
|
||||
private long mStartTime;
|
||||
private boolean mReverse = false;
|
||||
private boolean mRunning = false;
|
||||
private int mDuration = ANIMATION_DURATION;
|
||||
private float mAnimationInitialValue;
|
||||
//We don't use colors just with our drawable state because of animations
|
||||
private int mPressedColor;
|
||||
private int mFocusedColor;
|
||||
private int mDisabledColor;
|
||||
private int mRippleColor;
|
||||
private int mRippleBgColor;
|
||||
|
||||
public AlmostRippleDrawable(@NonNull ColorStateList tintStateList) {
|
||||
super(tintStateList);
|
||||
mInterpolator = new AccelerateDecelerateInterpolator();
|
||||
setColor(tintStateList);
|
||||
}
|
||||
|
||||
public void setColor(@NonNull ColorStateList tintStateList) {
|
||||
int defaultColor = tintStateList.getDefaultColor();
|
||||
mFocusedColor = tintStateList.getColorForState(new int[]{android.R.attr.state_enabled, android.R.attr.state_focused}, defaultColor);
|
||||
mPressedColor = tintStateList.getColorForState(new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}, defaultColor);
|
||||
mDisabledColor = tintStateList.getColorForState(new int[]{-android.R.attr.state_enabled}, defaultColor);
|
||||
|
||||
//The ripple should be partially transparent
|
||||
mFocusedColor = getModulatedAlphaColor(130, mFocusedColor);
|
||||
mPressedColor = getModulatedAlphaColor(130, mPressedColor);
|
||||
mDisabledColor = getModulatedAlphaColor(130, mDisabledColor);
|
||||
}
|
||||
|
||||
private static int getModulatedAlphaColor(int alphaValue, int originalColor) {
|
||||
int alpha = Color.alpha(originalColor);
|
||||
int scale = alphaValue + (alphaValue >> 7);
|
||||
alpha = alpha * scale >> 8;
|
||||
return Color.argb(alpha, Color.red(originalColor), Color.green(originalColor), Color.blue(originalColor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doDraw(Canvas canvas, Paint paint) {
|
||||
Rect bounds = getBounds();
|
||||
int size = Math.min(bounds.width(), bounds.height());
|
||||
float scale = mCurrentScale;
|
||||
int rippleColor = mRippleColor;
|
||||
int bgColor = mRippleBgColor;
|
||||
float radius = (size / 2);
|
||||
float radiusAnimated = radius * scale;
|
||||
if (scale > INACTIVE_SCALE) {
|
||||
if (bgColor != 0) {
|
||||
paint.setColor(bgColor);
|
||||
paint.setAlpha(decreasedAlpha(Color.alpha(bgColor)));
|
||||
canvas.drawCircle(bounds.centerX(), bounds.centerY(), radius, paint);
|
||||
}
|
||||
if (rippleColor != 0) {
|
||||
paint.setColor(rippleColor);
|
||||
paint.setAlpha(modulateAlpha(Color.alpha(rippleColor)));
|
||||
canvas.drawCircle(bounds.centerX(), bounds.centerY(), radiusAnimated, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int decreasedAlpha(int alpha) {
|
||||
int scale = 100 + (100 >> 7);
|
||||
return alpha * scale >> 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setState(int[] stateSet) {
|
||||
int[] oldState = getState();
|
||||
boolean oldPressed = false;
|
||||
for (int i : oldState) {
|
||||
if (i == android.R.attr.state_pressed) {
|
||||
oldPressed = true;
|
||||
}
|
||||
}
|
||||
super.setState(stateSet);
|
||||
boolean focused = false;
|
||||
boolean pressed = false;
|
||||
boolean disabled = true;
|
||||
for (int i : stateSet) {
|
||||
if (i == android.R.attr.state_focused) {
|
||||
focused = true;
|
||||
} else if (i == android.R.attr.state_pressed) {
|
||||
pressed = true;
|
||||
} else if (i == android.R.attr.state_enabled) {
|
||||
disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
unscheduleSelf(mUpdater);
|
||||
mRippleColor = mDisabledColor;
|
||||
mRippleBgColor = 0;
|
||||
mCurrentScale = ACTIVE_SCALE / 2;
|
||||
invalidateSelf();
|
||||
} else {
|
||||
if (pressed) {
|
||||
animateToPressed();
|
||||
mRippleColor = mRippleBgColor = mPressedColor;
|
||||
} else if (oldPressed) {
|
||||
mRippleColor = mRippleBgColor = mPressedColor;
|
||||
animateToNormal();
|
||||
} else if (focused) {
|
||||
mRippleColor = mFocusedColor;
|
||||
mRippleBgColor = 0;
|
||||
mCurrentScale = ACTIVE_SCALE;
|
||||
invalidateSelf();
|
||||
} else {
|
||||
mRippleColor = 0;
|
||||
mRippleBgColor = 0;
|
||||
mCurrentScale = INACTIVE_SCALE;
|
||||
invalidateSelf();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void animateToPressed() {
|
||||
unscheduleSelf(mUpdater);
|
||||
if (mCurrentScale < ACTIVE_SCALE) {
|
||||
mReverse = false;
|
||||
mRunning = true;
|
||||
mAnimationInitialValue = mCurrentScale;
|
||||
float durationFactor = 1f - ((mAnimationInitialValue - INACTIVE_SCALE) / (ACTIVE_SCALE - INACTIVE_SCALE));
|
||||
mDuration = (int) (ANIMATION_DURATION * durationFactor);
|
||||
mStartTime = SystemClock.uptimeMillis();
|
||||
scheduleSelf(mUpdater, mStartTime + FRAME_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
public void animateToNormal() {
|
||||
unscheduleSelf(mUpdater);
|
||||
if (mCurrentScale > INACTIVE_SCALE) {
|
||||
mReverse = true;
|
||||
mRunning = true;
|
||||
mAnimationInitialValue = mCurrentScale;
|
||||
float durationFactor = 1f - ((mAnimationInitialValue - ACTIVE_SCALE) / (INACTIVE_SCALE - ACTIVE_SCALE));
|
||||
mDuration = (int) (ANIMATION_DURATION * durationFactor);
|
||||
mStartTime = SystemClock.uptimeMillis();
|
||||
scheduleSelf(mUpdater, mStartTime + FRAME_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAnimation(float factor) {
|
||||
float initial = mAnimationInitialValue;
|
||||
float destination = mReverse ? INACTIVE_SCALE : ACTIVE_SCALE;
|
||||
mCurrentScale = initial + (destination - initial) * factor;
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
private final Runnable mUpdater = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
long currentTime = SystemClock.uptimeMillis();
|
||||
long diff = currentTime - mStartTime;
|
||||
if (diff < mDuration) {
|
||||
float interpolation = mInterpolator.getInterpolation((float) diff / (float) mDuration);
|
||||
scheduleSelf(mUpdater, currentTime + FRAME_DURATION);
|
||||
updateAnimation(interpolation);
|
||||
} else {
|
||||
unscheduleSelf(mUpdater);
|
||||
mRunning = false;
|
||||
updateAnimation(1f);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
//No-Op. We control our own animation
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
//No-Op. We control our own animation
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return mRunning;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
package com.yunbao.faceunity.seekbar.internal.drawable;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.os.SystemClock;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of {@link StateDrawable} to draw a morphing marker symbol.
|
||||
* <p>
|
||||
* It's basically an implementation of an {@link Animatable} Drawable with the following details:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>Animates from a circle shape to a "marker" shape just using a RoundRect</li>
|
||||
* <li>Animates color change from the normal state color to the pressed state color</li>
|
||||
* <li>Uses a {@link Path} to also serve as Outline for API>=21</li>
|
||||
* </ul>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class MarkerDrawable extends StateDrawable implements Animatable {
|
||||
private static final long FRAME_DURATION = 1000 / 60;
|
||||
private static final int ANIMATION_DURATION = 250;
|
||||
|
||||
private float mCurrentScale = 0f;
|
||||
private Interpolator mInterpolator;
|
||||
private long mStartTime;
|
||||
private boolean mReverse = false;
|
||||
private boolean mRunning = false;
|
||||
private int mDuration = ANIMATION_DURATION;
|
||||
//size of the actual thumb drawable to use as circle state size
|
||||
private float mClosedStateSize;
|
||||
//value to store que current scale when starting an animation and interpolate from it
|
||||
private float mAnimationInitialValue;
|
||||
//extra offset directed from the View to account
|
||||
//for its internal padding between circle state and marker state
|
||||
private int mExternalOffset;
|
||||
//colors for interpolation
|
||||
private int mStartColor;//Color when the Marker is OPEN
|
||||
private int mEndColor;//Color when the arker is CLOSED
|
||||
|
||||
Path mPath = new Path();
|
||||
RectF mRect = new RectF();
|
||||
Matrix mMatrix = new Matrix();
|
||||
private MarkerAnimationListener mMarkerListener;
|
||||
|
||||
public MarkerDrawable(@NonNull ColorStateList tintList, int closedSize) {
|
||||
super(tintList);
|
||||
mInterpolator = new AccelerateDecelerateInterpolator();
|
||||
mClosedStateSize = closedSize;
|
||||
mStartColor = tintList.getColorForState(new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}, tintList.getDefaultColor());
|
||||
mEndColor = tintList.getDefaultColor();
|
||||
|
||||
}
|
||||
|
||||
public void setExternalOffset(int offset) {
|
||||
mExternalOffset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* The two colors that will be used for the seek thumb.
|
||||
*
|
||||
* @param startColor Color used for the seek thumb
|
||||
* @param endColor Color used for popup indicator
|
||||
*/
|
||||
public void setColors(int startColor, int endColor) {
|
||||
mStartColor = startColor;
|
||||
mEndColor = endColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
void doDraw(Canvas canvas, Paint paint) {
|
||||
if (!mPath.isEmpty()) {
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
int color = blendColors(mStartColor, mEndColor, mCurrentScale);
|
||||
paint.setColor(color);
|
||||
canvas.drawPath(mPath, paint);
|
||||
}
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
return mPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
super.onBoundsChange(bounds);
|
||||
computePath(bounds);
|
||||
}
|
||||
|
||||
private void computePath(Rect bounds) {
|
||||
final float currentScale = mCurrentScale;
|
||||
final Path path = mPath;
|
||||
final RectF rect = mRect;
|
||||
final Matrix matrix = mMatrix;
|
||||
|
||||
path.reset();
|
||||
int totalSize = Math.min(bounds.width(), bounds.height());
|
||||
|
||||
float initial = mClosedStateSize;
|
||||
float destination = totalSize;
|
||||
float currentSize = initial + (destination - initial) * currentScale;
|
||||
|
||||
float halfSize = currentSize / 2f;
|
||||
float inverseScale = 1f - currentScale;
|
||||
float cornerSize = halfSize * inverseScale;
|
||||
float[] corners = new float[]{halfSize, halfSize, halfSize, halfSize, halfSize, halfSize, cornerSize, cornerSize};
|
||||
rect.set(bounds.left, bounds.top, bounds.left + currentSize, bounds.top + currentSize);
|
||||
path.addRoundRect(rect, corners, Path.Direction.CCW);
|
||||
matrix.reset();
|
||||
matrix.postRotate(-45, bounds.left + halfSize, bounds.top + halfSize);
|
||||
matrix.postTranslate((bounds.width() - currentSize) / 2, 0);
|
||||
float hDiff = (bounds.bottom - currentSize - mExternalOffset) * inverseScale;
|
||||
matrix.postTranslate(0, hDiff);
|
||||
path.transform(matrix);
|
||||
}
|
||||
|
||||
private void updateAnimation(float factor) {
|
||||
float initial = mAnimationInitialValue;
|
||||
float destination = mReverse ? 0f : 1f;
|
||||
mCurrentScale = initial + (destination - initial) * factor;
|
||||
computePath(getBounds());
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
public void animateToPressed() {
|
||||
unscheduleSelf(mUpdater);
|
||||
mReverse = false;
|
||||
if (mCurrentScale < 1) {
|
||||
mRunning = true;
|
||||
mAnimationInitialValue = mCurrentScale;
|
||||
float durationFactor = 1f - mCurrentScale;
|
||||
mDuration = (int) (ANIMATION_DURATION * durationFactor);
|
||||
mStartTime = SystemClock.uptimeMillis();
|
||||
scheduleSelf(mUpdater, mStartTime + FRAME_DURATION);
|
||||
} else {
|
||||
notifyFinishedToListener();
|
||||
}
|
||||
}
|
||||
|
||||
public void animateToNormal() {
|
||||
mReverse = true;
|
||||
unscheduleSelf(mUpdater);
|
||||
if (mCurrentScale > 0) {
|
||||
mRunning = true;
|
||||
mAnimationInitialValue = mCurrentScale;
|
||||
float durationFactor = 1f - mCurrentScale;
|
||||
mDuration = ANIMATION_DURATION - (int) (ANIMATION_DURATION * durationFactor);
|
||||
mStartTime = SystemClock.uptimeMillis();
|
||||
scheduleSelf(mUpdater, mStartTime + FRAME_DURATION);
|
||||
} else {
|
||||
notifyFinishedToListener();
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable mUpdater = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
long currentTime = SystemClock.uptimeMillis();
|
||||
long diff = currentTime - mStartTime;
|
||||
if (diff < mDuration) {
|
||||
float interpolation = mInterpolator.getInterpolation((float) diff / (float) mDuration);
|
||||
scheduleSelf(mUpdater, currentTime + FRAME_DURATION);
|
||||
updateAnimation(interpolation);
|
||||
} else {
|
||||
unscheduleSelf(mUpdater);
|
||||
mRunning = false;
|
||||
updateAnimation(1f);
|
||||
notifyFinishedToListener();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void setMarkerListener(MarkerAnimationListener listener) {
|
||||
mMarkerListener = listener;
|
||||
}
|
||||
|
||||
private void notifyFinishedToListener() {
|
||||
if (mMarkerListener != null) {
|
||||
if (mReverse) {
|
||||
mMarkerListener.onClosingComplete();
|
||||
} else {
|
||||
mMarkerListener.onOpeningComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
//No-Op. We control our own animation
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
unscheduleSelf(mUpdater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return mRunning;
|
||||
}
|
||||
|
||||
private static int blendColors(int color1, int color2, float factor) {
|
||||
final float inverseFactor = 1f - factor;
|
||||
float a = (Color.alpha(color1) * factor) + (Color.alpha(color2) * inverseFactor);
|
||||
float r = (Color.red(color1) * factor) + (Color.red(color2) * inverseFactor);
|
||||
float g = (Color.green(color1) * factor) + (Color.green(color2) * inverseFactor);
|
||||
float b = (Color.blue(color1) * factor) + (Color.blue(color2) * inverseFactor);
|
||||
return Color.argb((int) a, (int) r, (int) g, (int) b);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A listener interface to porpagate animation events
|
||||
* This is the "poor's man" AnimatorListener for this Drawable
|
||||
*/
|
||||
public interface MarkerAnimationListener {
|
||||
public void onClosingComplete();
|
||||
|
||||
public void onOpeningComplete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.yunbao.faceunity.seekbar.internal.drawable;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
||||
/**
|
||||
* A drawable that changes it's Paint color depending on the Drawable State
|
||||
* <p>
|
||||
* Subclasses should implement {@link #doDraw(Canvas, Paint)}
|
||||
* </p>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract class StateDrawable extends Drawable {
|
||||
private ColorStateList mTintStateList;
|
||||
private final Paint mPaint;
|
||||
private int mCurrentColor;
|
||||
private int mAlpha = 255;
|
||||
|
||||
public StateDrawable(@NonNull ColorStateList tintStateList) {
|
||||
super();
|
||||
setColorStateList(tintStateList);
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateful() {
|
||||
return (mTintStateList.isStateful()) || super.isStateful();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setState(int[] stateSet) {
|
||||
boolean handled = super.setState(stateSet);
|
||||
handled = updateTint(stateSet) || handled;
|
||||
return handled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
|
||||
private boolean updateTint(int[] state) {
|
||||
final int color = mTintStateList.getColorForState(state, mCurrentColor);
|
||||
if (color != mCurrentColor) {
|
||||
mCurrentColor = color;
|
||||
//We've changed states
|
||||
invalidateSelf();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
mPaint.setColor(mCurrentColor);
|
||||
int alpha = modulateAlpha(Color.alpha(mCurrentColor));
|
||||
mPaint.setAlpha(alpha);
|
||||
doDraw(canvas, mPaint);
|
||||
}
|
||||
|
||||
public void setColorStateList(@NonNull ColorStateList tintStateList) {
|
||||
mTintStateList = tintStateList;
|
||||
mCurrentColor = tintStateList.getDefaultColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should implement this method to do the actual drawing
|
||||
*
|
||||
* @param canvas The current {@link Canvas} to draw into
|
||||
* @param paint The {@link Paint} preconfigurred with the current
|
||||
* {@link ColorStateList} color
|
||||
*/
|
||||
abstract void doDraw(Canvas canvas, Paint paint);
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mAlpha = alpha;
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
int modulateAlpha(int alpha) {
|
||||
int scale = mAlpha + (mAlpha >> 7);
|
||||
return alpha * scale >> 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlpha() {
|
||||
return mAlpha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
mPaint.setColorFilter(cf);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.yunbao.faceunity.seekbar.internal.drawable;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.yunbao.faceunity.seekbar.internal.Marker;
|
||||
|
||||
|
||||
/**
|
||||
* <h1>HACK</h1>
|
||||
* <p>
|
||||
* Special {@link StateDrawable} implementation
|
||||
* to draw the Thumb circle.
|
||||
* </p>
|
||||
* <p>
|
||||
* It's special because it will stop drawing once the state is pressed/focused BUT only after a small delay.
|
||||
* </p>
|
||||
* <p>
|
||||
* This special delay is meant to help avoiding frame glitches while the {@link Marker} is added to the Window
|
||||
* </p>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class ThumbDrawable extends StateDrawable implements Animatable {
|
||||
//The current size for this drawable. Must be converted to real DPs
|
||||
public static final int DEFAULT_SIZE_DP = 12;
|
||||
private final int mSize;
|
||||
private boolean mOpen;
|
||||
private boolean mRunning;
|
||||
|
||||
public ThumbDrawable(@NonNull ColorStateList tintStateList, int size) {
|
||||
super(tintStateList);
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doDraw(Canvas canvas, Paint paint) {
|
||||
if (!mOpen) {
|
||||
Rect bounds = getBounds();
|
||||
float radius = (mSize / 2);
|
||||
canvas.drawCircle(bounds.centerX(), bounds.centerY(), radius, paint);
|
||||
}
|
||||
}
|
||||
|
||||
public void animateToPressed() {
|
||||
scheduleSelf(opener, SystemClock.uptimeMillis() + 100);
|
||||
mRunning = true;
|
||||
}
|
||||
|
||||
public void animateToNormal() {
|
||||
mOpen = false;
|
||||
mRunning = false;
|
||||
unscheduleSelf(opener);
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
private Runnable opener = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mOpen = true;
|
||||
invalidateSelf();
|
||||
mRunning = false;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
//NOOP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
animateToNormal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return mRunning;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.yunbao.faceunity.seekbar.internal.drawable;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
||||
/**
|
||||
* Simple {@link StateDrawable} implementation
|
||||
* to draw circles/ovals
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class TrackOvalDrawable extends StateDrawable {
|
||||
private RectF mRectF = new RectF();
|
||||
|
||||
public TrackOvalDrawable(@NonNull ColorStateList tintStateList) {
|
||||
super(tintStateList);
|
||||
}
|
||||
|
||||
@Override
|
||||
void doDraw(Canvas canvas, Paint paint) {
|
||||
mRectF.set(getBounds());
|
||||
canvas.drawOval(mRectF, paint);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.yunbao.faceunity.seekbar.internal.drawable;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
||||
/**
|
||||
* Simple {@link StateDrawable} implementation
|
||||
* to draw rectangles
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class TrackRectDrawable extends StateDrawable {
|
||||
public TrackRectDrawable(@NonNull ColorStateList tintStateList) {
|
||||
super(tintStateList);
|
||||
}
|
||||
|
||||
@Override
|
||||
void doDraw(Canvas canvas, Paint paint) {
|
||||
canvas.drawRect(getBounds(), paint);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
package com.yunbao.faceunity.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.yunbao.common.utils.ToastUtil;
|
||||
import com.yunbao.common.utils.WordUtil;
|
||||
import com.yunbao.faceunity.R;
|
||||
import com.yunbao.faceunity.adapters.ContainerRecyclerAdapter;
|
||||
import com.yunbao.faceunity.adapters.MenuGroupRecyclerAdapter;
|
||||
import com.yunbao.faceunity.adapters.vh.StyleViewHolder;
|
||||
import com.yunbao.faceunity.data.FaceParam;
|
||||
import com.yunbao.faceunity.data.FineStickerDataFactory;
|
||||
import com.yunbao.faceunity.entity.BaseBean;
|
||||
import com.yunbao.faceunity.entity.FunctionEnum;
|
||||
import com.yunbao.faceunity.entity.MakeupCustomClassBean;
|
||||
import com.yunbao.faceunity.entity.MenuGroupBean;
|
||||
import com.yunbao.faceunity.entity.net.FineStickerEntity;
|
||||
import com.yunbao.faceunity.entity.net.FineStickerTagEntity;
|
||||
import com.yunbao.faceunity.repo.AnimojiSource;
|
||||
import com.yunbao.faceunity.repo.BodyBeautySource;
|
||||
import com.yunbao.faceunity.repo.FaceBeautySource;
|
||||
import com.yunbao.faceunity.repo.MakeupSource;
|
||||
import com.yunbao.faceunity.repo.PropSource;
|
||||
import com.yunbao.faceunity.seekbar.DiscreteSeekBar;
|
||||
import com.yunbao.faceunity.utils.FaceSPUtils;
|
||||
import com.yunbao.faceunity.utils.net.StickerDownloadHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* DESC:
|
||||
* Created on 2021/4/26
|
||||
*/
|
||||
public class FaceUnityView extends LinearLayout implements StickerDownloadHelper.Callback {
|
||||
|
||||
private Context mContext;
|
||||
private RecyclerView menuGroup;
|
||||
private RecyclerView containerRecycler;
|
||||
private ContainerRecyclerAdapter containerAdapter;
|
||||
private TabLayout tabLayout;
|
||||
private TextView title;
|
||||
private LinearLayout menu2, menuDiy, reset, menu2Reset;
|
||||
private ImageView menu2Back, back, close, contrast;
|
||||
private DiscreteSeekBar seekBar;
|
||||
private IFaceUnityInter iFaceUnityInter;
|
||||
private ConstraintLayout titleLayout;
|
||||
private static final String TAG = "美颜";
|
||||
|
||||
public FaceUnityView(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
init();
|
||||
}
|
||||
|
||||
public FaceUnityView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
init();
|
||||
}
|
||||
|
||||
public FaceUnityView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
mContext = context;
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
private void init() {
|
||||
LayoutInflater.from(mContext).inflate(R.layout.layout_faceunity, this);
|
||||
initView();
|
||||
FineStickerDataFactory.getInstance().addCallback(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化View
|
||||
*/
|
||||
private void initView() {
|
||||
menuGroup = findViewById(R.id.menu_group);
|
||||
containerRecycler = findViewById(R.id.menu2_container_view);
|
||||
tabLayout = findViewById(R.id.menu2_tab);
|
||||
title = findViewById(R.id.menu_title);
|
||||
menu2 = findViewById(R.id.layout_faceunity_menu2);
|
||||
back = findViewById(R.id.menu_back);
|
||||
menu2Back = findViewById(R.id.menu2_back);
|
||||
close = findViewById(R.id.menu_close);
|
||||
reset = findViewById(R.id.menu_reset);
|
||||
menu2Reset = findViewById(R.id.menu2_reset);
|
||||
menuDiy = findViewById(R.id.menu_diy);
|
||||
seekBar = findViewById(R.id.item_seekBar);
|
||||
contrast = findViewById(R.id.item_contrast);
|
||||
titleLayout = findViewById(R.id.titleLayout);
|
||||
initMenuGroup();
|
||||
setContainerRecycler(new ArrayList<>());
|
||||
initViewClick();
|
||||
gotoFaceBeauty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化配置点击事件
|
||||
*/
|
||||
private void initViewClick() {
|
||||
menu2Back.setOnClickListener(v -> {
|
||||
Object tag = menu2Back.getTag();
|
||||
if (tag == null) {
|
||||
goBackMainMenu();
|
||||
} else if (tag.equals("makeup")) {
|
||||
title.setText(R.string.home_function_name_makeup);
|
||||
title.setVisibility(VISIBLE);
|
||||
menuDiy.setVisibility(VISIBLE);
|
||||
tabLayout.removeAllTabs();
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCombinations());
|
||||
menu2Back.setTag(null);
|
||||
}
|
||||
});
|
||||
menuDiy.setOnClickListener(v -> {
|
||||
menu2Back.setTag("makeup");
|
||||
changeRecyclerItemCount(5);
|
||||
menuDiy.setVisibility(GONE);
|
||||
ArrayList<MakeupCustomClassBean> list = MakeupSource.buildCustomClasses();
|
||||
setTab(createTabs(list));
|
||||
});
|
||||
menu2Reset.setOnClickListener(view -> {
|
||||
containerAdapter.reset();
|
||||
});
|
||||
|
||||
contrast.setOnTouchListener((v, event) -> {
|
||||
if (iFaceUnityInter == null) {
|
||||
return false;
|
||||
}
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
iFaceUnityInter.onPause();
|
||||
} else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
iFaceUnityInter.onStart();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 对比接口
|
||||
*/
|
||||
public void setIFaceUnityInter(IFaceUnityInter iFaceUnityInter) {
|
||||
this.iFaceUnityInter = iFaceUnityInter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 回到默认界面
|
||||
*/
|
||||
private void goBackMainMenu() {
|
||||
setContainerRecycler(new ArrayList<>());
|
||||
title.setText("美顏特效選擇");
|
||||
titleLayout.setVisibility(VISIBLE);
|
||||
title.setVisibility(VISIBLE);
|
||||
menu2.setVisibility(GONE);
|
||||
menuGroup.setVisibility(VISIBLE);
|
||||
menuDiy.setVisibility(GONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 目前只需要美颜功能,进入后直奔美颜
|
||||
*/
|
||||
private void gotoFaceBeauty() {
|
||||
LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
|
||||
map.put(R.string.beauty_radio_skin_beauty, FaceParam.FACE_BEAUTY_SKIN);
|
||||
map.put(R.string.beauty_radio_face_shape, FaceParam.FACE_BEAUTY_SHAPE);
|
||||
map.put(R.string.beauty_radio_filter, FaceParam.FACE_BEAUTY_FILTER);
|
||||
map.put(R.string.beauty_radio_style, FaceParam.FACE_BEAUTY_STYLE);
|
||||
setContainerRecycler(FaceBeautySource.buildSkinParams());
|
||||
changeRecyclerItemCount(2);
|
||||
setTab(createTabs(map));
|
||||
menuGroup.setVisibility(GONE);
|
||||
titleLayout.setVisibility(GONE);
|
||||
back.setVisibility(GONE);
|
||||
menu2Back.setVisibility(GONE);
|
||||
menu2.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置主菜单
|
||||
*/
|
||||
private void initMenuGroup() {
|
||||
MenuGroupRecyclerAdapter adapter = new MenuGroupRecyclerAdapter(mContext);
|
||||
menuGroup.setLayoutManager(new GridLayoutManager(mContext, 4));
|
||||
List<MenuGroupBean> layoutItem = new ArrayList<>();
|
||||
layoutItem.add(new MenuGroupBean(R.string.home_function_name_beauty, R.mipmap.ico_home_beauty));
|
||||
layoutItem.add(new MenuGroupBean(R.string.home_function_name_makeup, R.mipmap.ico_home_makeup));
|
||||
layoutItem.add(new MenuGroupBean(R.string.home_function_name_beauty_body, R.mipmap.ico_home_beauty_body));
|
||||
layoutItem.add(new MenuGroupBean(R.string.home_function_name_big_head, R.mipmap.ico_home_big_head));
|
||||
layoutItem.add(new MenuGroupBean(R.string.home_function_name_animoji, R.mipmap.ico_home_animoji));
|
||||
layoutItem.add(new MenuGroupBean(R.string.home_function_name_sticker, R.mipmap.ico_home_sticker));
|
||||
layoutItem.add(new MenuGroupBean(R.string.home_function_name_fine_sticker, R.mipmap.ico_home_fine_sticker));
|
||||
adapter.setList(layoutItem);
|
||||
adapter.setOnItemClickListener(position -> {
|
||||
LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
|
||||
title.setVisibility(GONE);
|
||||
switch (position) {
|
||||
case 0:
|
||||
map.put(R.string.beauty_radio_skin_beauty, FaceParam.FACE_BEAUTY_SKIN);
|
||||
map.put(R.string.beauty_radio_face_shape, FaceParam.FACE_BEAUTY_SHAPE);
|
||||
map.put(R.string.beauty_radio_filter, FaceParam.FACE_BEAUTY_FILTER);
|
||||
map.put(R.string.beauty_radio_style, FaceParam.FACE_BEAUTY_STYLE);
|
||||
setContainerRecycler(FaceBeautySource.buildSkinParams());
|
||||
break;
|
||||
case 1:
|
||||
title.setText(R.string.home_function_name_makeup);
|
||||
title.setVisibility(VISIBLE);
|
||||
menuDiy.setVisibility(VISIBLE);
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCombinations());
|
||||
break;
|
||||
case 2:
|
||||
title.setText(R.string.home_function_name_beauty_body);
|
||||
title.setVisibility(VISIBLE);
|
||||
changeRecyclerItemCount(2);
|
||||
setContainerRecycler(BodyBeautySource.buildBodyBeauty());
|
||||
break;
|
||||
case 3:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(PropSource.buildPropBeans(FunctionEnum.BIG_HEAD));
|
||||
break;
|
||||
case 4:
|
||||
changeRecyclerItemCount(5);
|
||||
map.put(R.string.animoji_filter, FaceParam.FACE_ANIMOJI);
|
||||
map.put(R.string.cartoon_filter, FaceParam.FACE_ANIM);
|
||||
setContainerRecycler(AnimojiSource.buildAnimojis());
|
||||
break;
|
||||
case 5:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(PropSource.buildPropBeans(FunctionEnum.STICKER));
|
||||
break;
|
||||
case 6:
|
||||
List<FineStickerTagEntity> tagList = FineStickerDataFactory.getInstance().loadTagList();
|
||||
if (!tagList.isEmpty()) {
|
||||
setTab(createTabs(tagList));
|
||||
}
|
||||
break;
|
||||
}
|
||||
setTab(createTabs(map));
|
||||
menuGroup.setVisibility(GONE);
|
||||
menu2.setVisibility(VISIBLE);
|
||||
});
|
||||
menuGroup.setAdapter(adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Tab
|
||||
*/
|
||||
private List<TabLayout.Tab> createTabs(Map<Integer, Integer> map) {
|
||||
List<TabLayout.Tab> list = new ArrayList<>();
|
||||
for (Integer key : map.keySet()) {
|
||||
TabLayout.Tab tab = tabLayout.newTab().setText(key);
|
||||
tab.setTag(map.get(key));
|
||||
list.add(tab);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建菜单
|
||||
*/
|
||||
private List<TabLayout.Tab> createTabs(List<FineStickerTagEntity> tags) {
|
||||
List<TabLayout.Tab> list = new ArrayList<>();
|
||||
for (FineStickerTagEntity tag : tags) {
|
||||
TabLayout.Tab tab;
|
||||
if (WordUtil.isZh()) {
|
||||
tab = tabLayout.newTab().setText(tag.getTag().split("/")[0]);
|
||||
} else {
|
||||
tab = tabLayout.newTab().setText(tag.getTag().split("/")[1]);
|
||||
}
|
||||
tab.setTag(tag);
|
||||
list.add(tab);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建菜单
|
||||
*/
|
||||
private List<TabLayout.Tab> createTabs(ArrayList<MakeupCustomClassBean> tags) {
|
||||
List<TabLayout.Tab> list = new ArrayList<>();
|
||||
for (MakeupCustomClassBean tag : tags) {
|
||||
TabLayout.Tab tab;
|
||||
tab = tabLayout.newTab().setText(tag.getDesRes());
|
||||
tab.setTag(tag.getBeanType());
|
||||
list.add(tab);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置菜单
|
||||
*/
|
||||
private void setTab(List<TabLayout.Tab> tabs) {
|
||||
tabLayout.removeAllTabs();
|
||||
for (TabLayout.Tab tab : tabs) {
|
||||
tabLayout.addTab(tab);
|
||||
if (tab.getTag() instanceof Integer) {
|
||||
if (FaceSPUtils.getInstance().getString(StyleViewHolder.class.getSimpleName() + "_") != null && (int) tab.getTag() == FaceParam.FACE_BEAUTY_STYLE) {
|
||||
ToastUtil.show("请先重置风格推荐");
|
||||
tab.select();
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(FaceBeautySource.buildStylesParams());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
Object tabTag = tab.getTag();
|
||||
if (tabTag instanceof Integer) {
|
||||
if (FaceSPUtils.getInstance().getString(StyleViewHolder.class.getSimpleName() + "_") != null && (int) tab.getTag() < FaceParam.FACE_BEAUTY_STYLE) {
|
||||
ToastUtil.show("请先重置风格推荐");
|
||||
tabLayout.getTabAt(3).select();
|
||||
return;
|
||||
}
|
||||
switch ((int) tab.getTag()) {
|
||||
case FaceParam.FACE_BEAUTY_SKIN:
|
||||
changeRecyclerItemCount(2);
|
||||
setContainerRecycler(FaceBeautySource.buildSkinParams());
|
||||
break;
|
||||
case FaceParam.FACE_BEAUTY_SHAPE:
|
||||
changeRecyclerItemCount(2);
|
||||
setContainerRecycler(FaceBeautySource.buildShapeParams());
|
||||
break;
|
||||
case FaceParam.FACE_BEAUTY_FILTER:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(FaceBeautySource.buildFilters());
|
||||
break;
|
||||
case FaceParam.FACE_BEAUTY_STYLE:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(FaceBeautySource.buildStylesParams());
|
||||
break;
|
||||
case FaceParam.FACE_ANIMOJI:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(AnimojiSource.buildAnimojis());
|
||||
break;
|
||||
case FaceParam.FACE_ANIM:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(AnimojiSource.buildFilters());
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_FOUNDATION:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCustomItemParams().get(MakeupSource.FACE_MAKEUP_TYPE_FOUNDATION));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_LIP_STICK:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCustomItemParams().get(MakeupSource.FACE_MAKEUP_TYPE_LIP_STICK));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_BLUSHER:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCustomItemParams().get(MakeupSource.FACE_MAKEUP_TYPE_BLUSHER));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_BROW:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCustomItemParams().get(MakeupSource.FACE_MAKEUP_TYPE_EYE_BROW));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_SHADOW:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCustomItemParams().get(MakeupSource.FACE_MAKEUP_TYPE_EYE_SHADOW));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_LINER:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCustomItemParams().get(MakeupSource.FACE_MAKEUP_TYPE_EYE_LINER));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_LASH:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCustomItemParams().get(MakeupSource.FACE_MAKEUP_TYPE_EYE_LASH));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_HIGH_LIGHT:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCustomItemParams().get(MakeupSource.FACE_MAKEUP_TYPE_HIGH_LIGHT));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_SHADOW:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCustomItemParams().get(MakeupSource.FACE_MAKEUP_TYPE_SHADOW));
|
||||
break;
|
||||
case FaceParam.FACE_MAKEUP_TYPE_EYE_PUPIL:
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(MakeupSource.buildCustomItemParams().get(MakeupSource.FACE_MAKEUP_TYPE_EYE_PUPIL));
|
||||
break;
|
||||
default:
|
||||
setContainerRecycler(new ArrayList<>());
|
||||
}
|
||||
} else if (tabTag instanceof FineStickerTagEntity) {
|
||||
FineStickerTagEntity tag = (FineStickerTagEntity) tabTag;
|
||||
FineStickerEntity sticker = FineStickerDataFactory.getInstance().loadStickerList(tag);
|
||||
ArrayList<FineStickerEntity.DocsBean> list = new ArrayList<>();
|
||||
FineStickerEntity.DocsBean docsBean = new FineStickerEntity.DocsBean();
|
||||
docsBean.set_id("-1");
|
||||
list.add(docsBean);
|
||||
list.addAll(sticker.getDocs());
|
||||
changeRecyclerItemCount(5);
|
||||
setContainerRecycler(list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置美颜选项配置行数,图标为5个,拖动条为2个
|
||||
*
|
||||
* @param count
|
||||
*/
|
||||
private void changeRecyclerItemCount(int count) {
|
||||
containerRecycler.setLayoutManager(new GridLayoutManager(mContext, count));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置美颜Recycler内容
|
||||
*
|
||||
* @param list
|
||||
*/
|
||||
private void setContainerRecycler(ArrayList<? extends BaseBean> list) {
|
||||
if (containerAdapter == null) {
|
||||
containerAdapter = new ContainerRecyclerAdapter(mContext);
|
||||
containerAdapter.setSeekBar(seekBar);
|
||||
containerRecycler.setLayoutManager(new GridLayoutManager(mContext, 2));
|
||||
containerRecycler.setAdapter(containerAdapter);
|
||||
}
|
||||
// titleLayout.setVisibility(title.getVisibility()==GONE?INVISIBLE:VISIBLE);
|
||||
// Log.i(TAG, "setContainerRecycler: " + list.size());
|
||||
containerAdapter.setList(list);
|
||||
containerAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetTags(String[] tags) {
|
||||
List<FineStickerTagEntity> list = FineStickerDataFactory.formatTag(tags);
|
||||
setTab(createTabs(list));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetList(String tag, FineStickerEntity fineSticker) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownload(FineStickerEntity.DocsBean entity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadError(FineStickerEntity.DocsBean entity, String msg) {
|
||||
|
||||
}
|
||||
|
||||
public interface IFaceUnityInter {
|
||||
void onPause();
|
||||
|
||||
void onStart();
|
||||
}
|
||||
}
|
||||
1259
FaceUnity/src/main/java/com/yunbao/faceunity/utils/Authpack.java
Normal file
1259
FaceUnity/src/main/java/com/yunbao/faceunity/utils/Authpack.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,172 @@
|
||||
package com.yunbao.faceunity.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
/**
|
||||
* cpu使用率获取工具类
|
||||
* Created by lirui on 2017/8/2.
|
||||
*/
|
||||
|
||||
public class CPUInfoUtil {
|
||||
private long lastTotalCpu = 0;
|
||||
private long lastProcessCpu = 0;
|
||||
|
||||
private final String PackageName;
|
||||
|
||||
private volatile boolean isRunningCPU = false;
|
||||
private volatile double cpuRate = 0;
|
||||
|
||||
public CPUInfoUtil(Context context) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
final String pn = context.getPackageName();
|
||||
if (pn.length() <= 16) {
|
||||
PackageName = pn;
|
||||
} else {
|
||||
PackageName = pn.substring(0, 15) + "+";
|
||||
}
|
||||
// Log.e(TAG, "CSVUtils PackageName " + PackageName);
|
||||
isRunningCPU = true;
|
||||
CPUInfoThread cpuinfothread = new CPUInfoThread();
|
||||
cpuinfothread.start();
|
||||
} else {
|
||||
PackageName = null;
|
||||
}
|
||||
}
|
||||
|
||||
public double getProcessCpuUsed() {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
return cpuRate;
|
||||
} else {
|
||||
double pcpu = 0;
|
||||
double tmp = 1.0;
|
||||
long nowTotalCpu = getTotalCpu();
|
||||
long nowProcessCpu = getMyProcessCpu();
|
||||
if (nowTotalCpu != 0 && (nowTotalCpu - lastTotalCpu) != 0) {
|
||||
// Log.e(TAG, "cpu used nowProcessCpu " + nowProcessCpu + " lastProcessCpu " + lastProcessCpu + " nowTotalCpu " + nowTotalCpu + " lastTotalCpu " + lastTotalCpu);
|
||||
pcpu = 100 * (tmp * (nowProcessCpu - lastProcessCpu) / (nowTotalCpu - lastTotalCpu));
|
||||
}
|
||||
lastProcessCpu = nowProcessCpu;
|
||||
lastTotalCpu = nowTotalCpu;
|
||||
return pcpu < 0 ? 0 : pcpu;
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
isRunningCPU = false;
|
||||
}
|
||||
}
|
||||
|
||||
private long getTotalCpu() {
|
||||
String[] cpuInfos = null;
|
||||
try {
|
||||
RandomAccessFile reader = null;
|
||||
reader = new RandomAccessFile("/proc/stat", "r");
|
||||
String load = reader.readLine();
|
||||
reader.close();
|
||||
cpuInfos = load.split(" ");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
long totalCpu = 0;
|
||||
try {
|
||||
totalCpu = Long.parseLong(cpuInfos[2])
|
||||
+ Long.parseLong(cpuInfos[3]) + Long.parseLong(cpuInfos[4])
|
||||
+ Long.parseLong(cpuInfos[6]) + Long.parseLong(cpuInfos[5])
|
||||
+ Long.parseLong(cpuInfos[7]) + Long.parseLong(cpuInfos[8]);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
return totalCpu;
|
||||
}
|
||||
|
||||
private long getMyProcessCpu() {
|
||||
String[] cpuInfos = null;
|
||||
try {
|
||||
int pid = android.os.Process.myPid();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream("/proc/" + pid + "/stat")), 1000);
|
||||
String load = reader.readLine();
|
||||
reader.close();
|
||||
cpuInfos = load.split(" ");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
long appCpuTime = 0;
|
||||
try {
|
||||
appCpuTime = Long.parseLong(cpuInfos[13])
|
||||
+ Long.parseLong(cpuInfos[14]) + Long.parseLong(cpuInfos[15])
|
||||
+ Long.parseLong(cpuInfos[16]);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
return appCpuTime;
|
||||
}
|
||||
|
||||
class CPUInfoThread extends Thread {
|
||||
|
||||
private double allCPU = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String line = null;
|
||||
InputStream is = null;
|
||||
try {
|
||||
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
Process proc = runtime.exec("top -d 1");
|
||||
is = proc.getInputStream();
|
||||
|
||||
// 换成BufferedReader
|
||||
BufferedReader buf = new BufferedReader(new InputStreamReader(is));
|
||||
do {
|
||||
line = buf.readLine();
|
||||
if (allCPU == 0 && line.contains("user") && line.contains("nice") && line.contains("sys") && line.contains("idle") && line.contains("iow") && line.contains("irq") && line.contains("sirq") && line.contains("host")) {
|
||||
if (line.indexOf("%cpu ") > 0)
|
||||
allCPU = Double.parseDouble(line.split("%cpu ")[0]);
|
||||
if (allCPU == 0) {
|
||||
String[] s = line.split("%,");
|
||||
for (String st : s) {
|
||||
String[] sts = st.split(" ");
|
||||
if (sts.length > 0)
|
||||
allCPU += Double.parseDouble(sts[sts.length - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 读取到相应pkgName跳出循环(或者未找到)
|
||||
if (line == null || line.endsWith(PackageName)) {
|
||||
// Log.e(TAG, "cpu line : " + line);
|
||||
String str[] = line.split(" ");
|
||||
int t = 0;
|
||||
for (int i = str.length - 1; i > 0; i--) {
|
||||
if (!str[i].isEmpty() && ++t == 4) {
|
||||
// Log.e(TAG, "cpu : " + str[i] + " allCPU " + allCPU);
|
||||
cpuRate = 100 * Double.parseDouble(str[i]) / allCPU;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} while (isRunningCPU);
|
||||
|
||||
if (is != null) {
|
||||
buf.close();
|
||||
is.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
168
FaceUnity/src/main/java/com/yunbao/faceunity/utils/CSVUtils.java
Normal file
168
FaceUnity/src/main/java/com/yunbao/faceunity/utils/CSVUtils.java
Normal file
@@ -0,0 +1,168 @@
|
||||
package com.yunbao.faceunity.utils;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Created by tujh on 2017/11/2.
|
||||
*/
|
||||
public class CSVUtils {
|
||||
public static final String TAG = CSVUtils.class.getSimpleName();
|
||||
/* 每 100 帧统计一次 */
|
||||
public static final int FRAME_STEP = 100;
|
||||
|
||||
public static final String COMMA = ",";
|
||||
|
||||
private OutputStreamWriter mStreamWriter;
|
||||
|
||||
private ActivityManager mActivityManager;
|
||||
|
||||
private Handler mHandler;
|
||||
|
||||
private CPUInfoUtil mCPUInfoUtil;
|
||||
|
||||
private int mFrameRate;
|
||||
private volatile double mCpuUsed;
|
||||
private volatile double mAverageFps;
|
||||
private volatile double mAverageRenderTime;
|
||||
private volatile double mMemory;
|
||||
private long mSumRenderTimeInNano;
|
||||
private volatile long mTimestamp;
|
||||
|
||||
public CSVUtils(Context context) {
|
||||
mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
mCPUInfoUtil = new CPUInfoUtil(context);
|
||||
|
||||
HandlerThread handlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
|
||||
handlerThread.start();
|
||||
mHandler = new Handler(handlerThread.getLooper());
|
||||
}
|
||||
|
||||
public void initHeader(String folderName, StringBuilder headerInfo) {
|
||||
Log.d(TAG, "initHeader() called with: folderName = [" + folderName + "], headerInfo = [" + headerInfo + "]");
|
||||
StringBuilder stringBuilder = new StringBuilder().append("时间").append(COMMA)
|
||||
.append("帧率").append(COMMA)
|
||||
.append("渲染耗时").append(COMMA)
|
||||
.append("CPU").append(COMMA)
|
||||
.append("内存").append(COMMA);
|
||||
if (headerInfo != null) {
|
||||
stringBuilder.append(headerInfo);
|
||||
}
|
||||
stringBuilder.append("\n");
|
||||
|
||||
File file = new File(folderName);
|
||||
File parentFile = file.getParentFile();
|
||||
if (!parentFile.exists()) {
|
||||
parentFile.mkdirs();
|
||||
}
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
mStreamWriter = new OutputStreamWriter(new FileOutputStream(file, false), "GBK");
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "CSVUtils: ", e);
|
||||
}
|
||||
flush(stringBuilder);
|
||||
mTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void writeCsv(final StringBuilder extraInfo, long renderTimeInNano) {
|
||||
if (mStreamWriter == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSumRenderTimeInNano += renderTimeInNano;
|
||||
if (mFrameRate % FRAME_STEP == FRAME_STEP - 1) {
|
||||
mTimestamp = System.currentTimeMillis();
|
||||
mAverageFps = FPSUtil.fpsAVG(FRAME_STEP);
|
||||
mAverageRenderTime = (double) mSumRenderTimeInNano / FRAME_STEP / 1_000_000;
|
||||
mSumRenderTimeInNano = 0;
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mCpuUsed = mCPUInfoUtil.getProcessCpuUsed();
|
||||
mMemory = MemoryInfoUtil.getMemory(mActivityManager.getProcessMemoryInfo(new int[]{Process.myPid()}));
|
||||
String strCPU = String.format(Locale.getDefault(), "%.2f", mCpuUsed);
|
||||
String strMemory = String.format(Locale.getDefault(), "%.2f", mMemory);
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS", Locale.getDefault());
|
||||
|
||||
stringBuilder.append(dateFormat.format(new Date(mTimestamp))).append(COMMA)
|
||||
.append(String.format(Locale.getDefault(), "%.2f", mAverageFps)).append(COMMA)
|
||||
.append(String.format(Locale.getDefault(), "%.2f", mAverageRenderTime)).append(COMMA)
|
||||
.append(strCPU).append(COMMA)
|
||||
.append(strMemory).append(COMMA);
|
||||
|
||||
if (extraInfo != null) {
|
||||
stringBuilder.append(extraInfo);
|
||||
}
|
||||
stringBuilder.append("\n");
|
||||
flush(stringBuilder);
|
||||
}
|
||||
});
|
||||
}
|
||||
mFrameRate++;
|
||||
}
|
||||
|
||||
private void flush(StringBuilder stringBuilder) {
|
||||
if (mStreamWriter == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mStreamWriter.write(stringBuilder.toString());
|
||||
mStreamWriter.flush();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "flush: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
Log.d(TAG, "close: ");
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mStreamWriter != null) {
|
||||
try {
|
||||
mStreamWriter.close();
|
||||
mStreamWriter = null;
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "close: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
mHandler.getLooper().quitSafely();
|
||||
mHandler = null;
|
||||
mCPUInfoUtil.close();
|
||||
}
|
||||
|
||||
public double getCpuUsed() {
|
||||
return mCpuUsed;
|
||||
}
|
||||
|
||||
public double getMemory() {
|
||||
return mMemory;
|
||||
}
|
||||
|
||||
public double getAverageRenderTime() {
|
||||
return mAverageRenderTime;
|
||||
}
|
||||
|
||||
public double getAverageFps() {
|
||||
return mAverageFps;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.yunbao.faceunity.utils;
|
||||
|
||||
/**
|
||||
* FPS工具类
|
||||
* Created by tujh on 2018/5/24.
|
||||
*/
|
||||
public class FPSUtil {
|
||||
private static final int NANO_IN_ONE_MILLI_SECOND = 1000000;
|
||||
private static final int NANO_IN_ONE_SECOND = 1000 * NANO_IN_ONE_MILLI_SECOND;
|
||||
|
||||
private static long sLastFrameTimeStamp = 0;
|
||||
|
||||
/**
|
||||
* 每帧都计算
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static double fps() {
|
||||
long tmp = System.nanoTime();
|
||||
double fps = ((double) NANO_IN_ONE_SECOND) / (tmp - sLastFrameTimeStamp);
|
||||
sLastFrameTimeStamp = tmp;
|
||||
// Log.e(TAG, "FPS : " + fps);
|
||||
return fps;
|
||||
}
|
||||
|
||||
private static long mStartTime = 0;
|
||||
|
||||
/**
|
||||
* 平均值
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static double fpsAVG(int time) {
|
||||
long tmp = System.nanoTime();
|
||||
double fps = ((double) NANO_IN_ONE_SECOND) * time / (tmp - mStartTime);
|
||||
mStartTime = tmp;
|
||||
// Log.e(TAG, "FPS : " + fps);
|
||||
return fps;
|
||||
}
|
||||
|
||||
private long mLimitMinTime = 33333333;
|
||||
private long mLimitStartTime;
|
||||
private int mLimitFrameRate;
|
||||
|
||||
public void setLimitMinTime(long limitMinTime) {
|
||||
mLimitMinTime = limitMinTime;
|
||||
}
|
||||
|
||||
public void limit() {
|
||||
try {
|
||||
if (mLimitFrameRate == 0 || mLimitFrameRate > 600000) {
|
||||
mLimitStartTime = System.nanoTime();
|
||||
mLimitFrameRate = 0;
|
||||
}
|
||||
long sleepTime = mLimitMinTime * mLimitFrameRate++ - (System.nanoTime() - mLimitStartTime);
|
||||
if (sleepTime > 0) {
|
||||
Thread.sleep(sleepTime / NANO_IN_ONE_MILLI_SECOND, (int) (sleepTime % NANO_IN_ONE_MILLI_SECOND));
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
package com.yunbao.faceunity.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.Camera;
|
||||
|
||||
import com.faceunity.core.callback.OperateCallback;
|
||||
import com.faceunity.core.entity.FURenderInputData;
|
||||
import com.faceunity.core.entity.FURenderOutputData;
|
||||
import com.faceunity.core.enumeration.CameraFacingEnum;
|
||||
import com.faceunity.core.enumeration.FUAIProcessorEnum;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FURenderConfig;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.faceunity.FURenderManager;
|
||||
import com.faceunity.core.utils.CameraUtils;
|
||||
import com.faceunity.core.utils.FULogger;
|
||||
import com.yunbao.faceunity.listener.FURendererListener;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* DESC:
|
||||
* Created on 2021/4/26
|
||||
*/
|
||||
public class FURenderer extends IFURenderer {
|
||||
|
||||
private static final String TAG = "FURenderer";
|
||||
|
||||
public volatile static FURenderer INSTANCE;
|
||||
|
||||
public static FURenderer getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (FURenderer.class) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new FURenderer();
|
||||
INSTANCE.mFURenderKit = FURenderKit.getInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态回调监听
|
||||
*/
|
||||
private FURendererListener mFURendererListener;
|
||||
|
||||
|
||||
/* 特效FURenderKit*/
|
||||
public FURenderKit mFURenderKit;
|
||||
|
||||
/* AI道具*/
|
||||
public static String BUNDLE_AI_FACE = "model" + File.separator + "ai_face_processor.bundle";
|
||||
public static String BUNDLE_AI_HUMAN = "model" + File.separator + "ai_human_processor.bundle";
|
||||
|
||||
/* GL 线程 ID */
|
||||
private Long mGlThreadId = 0L;
|
||||
/* 任务队列 */
|
||||
private ArrayList<Runnable> mEventQueue = new ArrayList<>(16);
|
||||
private final Object queueLock = new Object();
|
||||
/* 渲染开关标识 */
|
||||
private volatile boolean mRendererSwitch = false;
|
||||
/* 清除队列标识 */
|
||||
private volatile boolean mClearQueue = false;
|
||||
|
||||
/* 相机角度-朝向映射 */
|
||||
private HashMap<Integer, CameraFacingEnum> cameraOrientationMap = new HashMap<>();
|
||||
|
||||
/*检测类型*/
|
||||
private FUAIProcessorEnum aIProcess = FUAIProcessorEnum.FACE_PROCESSOR;
|
||||
/*检测标识*/
|
||||
private int aIProcessTrackStatus = -1;
|
||||
|
||||
public String getVersion() {
|
||||
return mFURenderKit.getVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化鉴权
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
@Override
|
||||
public void setup(Context context) {
|
||||
FURenderManager.setKitDebug(FULogger.LogLevel.INFO);
|
||||
FURenderManager.setCoreDebug(FULogger.LogLevel.INFO);
|
||||
FURenderManager.registerFURender(context, Authpack.A(), new OperateCallback() {
|
||||
@Override
|
||||
public void onSuccess(int i, @NotNull String s) {
|
||||
if (i == FURenderConfig.OPERATE_SUCCESS_AUTH) {
|
||||
mFURenderKit.getFUAIController().loadAIProcessor(BUNDLE_AI_FACE, FUAITypeEnum.FUAITYPE_FACEPROCESSOR);
|
||||
mFURenderKit.getFUAIController().loadAIProcessor(BUNDLE_AI_HUMAN, FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
mFURenderKit.setReadBackSync(true);
|
||||
int cameraFrontOrientation = CameraUtils.INSTANCE.getCameraOrientation(Camera.CameraInfo.CAMERA_FACING_FRONT);
|
||||
int cameraBackOrientation = CameraUtils.INSTANCE.getCameraOrientation(Camera.CameraInfo.CAMERA_FACING_BACK);
|
||||
cameraOrientationMap.put(cameraFrontOrientation, CameraFacingEnum.CAMERA_FRONT);
|
||||
cameraOrientationMap.put(cameraBackOrientation, CameraFacingEnum.CAMERA_BACK);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int i, @NotNull String s) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启合成状态
|
||||
*/
|
||||
@Override
|
||||
public void prepareRenderer(FURendererListener mFURendererListener) {
|
||||
this.mFURendererListener = mFURendererListener;
|
||||
mRendererSwitch = true;
|
||||
mClearQueue = false;
|
||||
queueEvent(() -> mGlThreadId = Thread.currentThread().getId());
|
||||
mFURendererListener.onPrepare();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 双输入接口,输入 buffer 和 texture,必须在具有 GL 环境的线程调用
|
||||
* 由于省去数据拷贝,性能相对最优,优先推荐使用。
|
||||
* 缺点是无法保证 buffer 和纹理对齐,可能出现点位和效果对不上的情况。
|
||||
*
|
||||
* @param img NV21 buffer
|
||||
* @param texId 纹理 ID
|
||||
* @param width 宽
|
||||
* @param height 高
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int onDrawFrameDualInput(byte[] img, int texId, int width, int height) {
|
||||
prepareDrawFrame();
|
||||
if (!mRendererSwitch) {
|
||||
return texId;
|
||||
}
|
||||
FURenderInputData inputData = new FURenderInputData(width, height);
|
||||
if (img != null) {
|
||||
inputData.setImageBuffer(new FURenderInputData.FUImageBuffer(inputBufferType, img));
|
||||
}
|
||||
if (texId != -1) {
|
||||
inputData.setTexture(new FURenderInputData.FUTexture(inputTextureType, texId));
|
||||
}
|
||||
FURenderInputData.FURenderConfig config = inputData.getRenderConfig();
|
||||
config.setExternalInputType(externalInputType);
|
||||
config.setInputOrientation(inputOrientation);
|
||||
config.setDeviceOrientation(deviceOrientation);
|
||||
config.setInputBufferMatrix(inputBufferMatrix);
|
||||
config.setInputTextureMatrix(inputTextureMatrix);
|
||||
config.setOutputMatrix(outputMatrix);
|
||||
config.setCameraFacing(cameraFacing);
|
||||
FURenderOutputData outputData = mFURenderKit.renderWithInput(inputData);
|
||||
if (outputData.getTexture() != null && outputData.getTexture().getTexId() > 0) {
|
||||
return outputData.getTexture().getTexId();
|
||||
}
|
||||
return texId;
|
||||
}
|
||||
|
||||
public FURenderOutputData onDrawFrameInputWithReturn(byte[] img, int width, int height) {
|
||||
prepareDrawFrame();
|
||||
if (!mRendererSwitch) {
|
||||
return null ;
|
||||
}
|
||||
FURenderInputData inputData = new FURenderInputData(width, height);
|
||||
if (img != null) {
|
||||
inputData.setImageBuffer(new FURenderInputData.FUImageBuffer(inputBufferType, img));
|
||||
}
|
||||
FURenderInputData.FURenderConfig config = inputData.getRenderConfig();
|
||||
config.setExternalInputType(externalInputType);
|
||||
config.setInputOrientation(inputOrientation);
|
||||
config.setDeviceOrientation(deviceOrientation);
|
||||
config.setInputBufferMatrix(inputBufferMatrix);
|
||||
config.setInputTextureMatrix(inputTextureMatrix);
|
||||
config.setCameraFacing(cameraFacing);
|
||||
config.setNeedBufferReturn(true);
|
||||
config.setOutputMatrix(outputMatrix);
|
||||
return mFURenderKit.renderWithInput(inputData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 类似 GLSurfaceView 的 queueEvent 机制,把任务抛到 GL 线程执行。
|
||||
*
|
||||
* @param runnable
|
||||
*/
|
||||
@Override
|
||||
public void queueEvent(Runnable runnable) {
|
||||
if (runnable == null) {
|
||||
return;
|
||||
}
|
||||
if (mGlThreadId == Thread.currentThread().getId()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
synchronized (queueLock) {
|
||||
mEventQueue.add(runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 释放资源
|
||||
*/
|
||||
@Override
|
||||
public void release() {
|
||||
mRendererSwitch = false;
|
||||
mClearQueue = true;
|
||||
mGlThreadId = 0L;
|
||||
synchronized (queueLock) {
|
||||
mEventQueue.clear();
|
||||
mClearQueue = false;
|
||||
mFURenderKit.release();
|
||||
aIProcessTrackStatus = -1;
|
||||
if (mFURendererListener != null) {
|
||||
mFURendererListener.onRelease();
|
||||
mFURendererListener = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 渲染前置执行
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private void prepareDrawFrame() {
|
||||
benchmarkFPS();
|
||||
|
||||
// 执行任务队列中的任务
|
||||
synchronized (queueLock) {
|
||||
while (!mEventQueue.isEmpty() && !mClearQueue) {
|
||||
mEventQueue.remove(0).run();
|
||||
}
|
||||
}
|
||||
// AI检测
|
||||
trackStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置检测类型
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
@Override
|
||||
public void setAIProcessTrackType(FUAIProcessorEnum type) {
|
||||
aIProcess = type;
|
||||
aIProcessTrackStatus = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置FPS检测
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
@Override
|
||||
public void setMarkFPSEnable(boolean enable) {
|
||||
mIsRunBenchmark = enable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputOrientation(int inputOrientation) {
|
||||
if (cameraOrientationMap.containsKey(inputOrientation)) {
|
||||
setCameraFacing(cameraOrientationMap.get(inputOrientation));
|
||||
}
|
||||
super.setInputOrientation(inputOrientation);
|
||||
}
|
||||
|
||||
/**
|
||||
* AI识别数目检测
|
||||
*/
|
||||
private void trackStatus() {
|
||||
int trackCount;
|
||||
if (aIProcess == FUAIProcessorEnum.HAND_GESTURE_PROCESSOR) {
|
||||
trackCount = mFURenderKit.getFUAIController().handProcessorGetNumResults();
|
||||
} else if (aIProcess == FUAIProcessorEnum.HUMAN_PROCESSOR) {
|
||||
trackCount = mFURenderKit.getFUAIController().humanProcessorGetNumResults();
|
||||
} else {
|
||||
trackCount = mFURenderKit.getFUAIController().isTracking();
|
||||
}
|
||||
if (trackCount != aIProcessTrackStatus) {
|
||||
aIProcessTrackStatus = trackCount;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (mFURendererListener != null) {
|
||||
mFURendererListener.onTrackStatusChanged(aIProcess, trackCount);
|
||||
}
|
||||
}
|
||||
//endregion AI识别
|
||||
|
||||
//------------------------------FPS 渲染时长回调相关定义------------------------------------
|
||||
|
||||
private static final int NANO_IN_ONE_MILLI_SECOND = 1_000_000;
|
||||
private static final int NANO_IN_ONE_SECOND = 1_000_000_000;
|
||||
private static final int FRAME_COUNT = 20;
|
||||
private boolean mIsRunBenchmark = false;
|
||||
private int mCurrentFrameCount;
|
||||
private long mLastFrameTimestamp;
|
||||
private long mSumCallTime;
|
||||
private long mCallStartTime;
|
||||
|
||||
private void benchmarkFPS() {
|
||||
if (!mIsRunBenchmark) {
|
||||
return;
|
||||
}
|
||||
if (++mCurrentFrameCount == FRAME_COUNT) {
|
||||
long tmp = System.nanoTime();
|
||||
double fps = (double) NANO_IN_ONE_SECOND / ((double) (tmp - mLastFrameTimestamp) / FRAME_COUNT);
|
||||
double renderTime = (double) mSumCallTime / FRAME_COUNT / NANO_IN_ONE_MILLI_SECOND;
|
||||
mLastFrameTimestamp = tmp;
|
||||
mSumCallTime = 0;
|
||||
mCurrentFrameCount = 0;
|
||||
|
||||
if (mFURendererListener != null) {
|
||||
mFURendererListener.onFpsChanged(fps, renderTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
271
FaceUnity/src/main/java/com/yunbao/faceunity/utils/FUUtils.java
Normal file
271
FaceUnity/src/main/java/com/yunbao/faceunity/utils/FUUtils.java
Normal file
@@ -0,0 +1,271 @@
|
||||
package com.yunbao.faceunity.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import com.faceunity.core.model.facebeauty.FaceBeauty;
|
||||
import com.google.gson.Gson;
|
||||
import com.yunbao.faceunity.data.FaceBeautyData;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyFilterBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 将FaceBeauty FaceBeautyData 互相设置
|
||||
*/
|
||||
public class FUUtils {
|
||||
private static final String SP_NAME = "FaceBeauty";
|
||||
private static final String SP_KEY_NAME = "faceBeautyData";
|
||||
|
||||
/**
|
||||
* 将FaceBeauty 转 FaceBeautyData
|
||||
*
|
||||
* @param faceBeautyData
|
||||
*/
|
||||
public static void buildFaceBeautyData(FaceBeautyData faceBeautyData, FaceBeauty faceBeauty, ArrayList<FaceBeautyFilterBean> filterList, int styleTypeIndex) {
|
||||
if (faceBeauty != null) {
|
||||
/* 美肤 */
|
||||
/* 磨皮类型 */
|
||||
faceBeautyData.blurType = faceBeauty.getBlurType();
|
||||
/* 磨皮程度 */
|
||||
faceBeautyData.blurIntensity = faceBeauty.getBlurIntensity();
|
||||
/* 美白程度 */
|
||||
faceBeautyData.colorIntensity = faceBeauty.getColorIntensity();
|
||||
/* 红润程度 */
|
||||
faceBeautyData.redIntensity = faceBeauty.getRedIntensity();
|
||||
/* 锐化程度 */
|
||||
faceBeautyData.sharpenIntensity = faceBeauty.getSharpenIntensity();
|
||||
/* 亮眼程度 */
|
||||
faceBeautyData.eyeBrightIntensity = faceBeauty.getEyeBrightIntensity();
|
||||
/* 美牙程度 */
|
||||
faceBeautyData.toothIntensity = faceBeauty.getToothIntensity();
|
||||
/* 去黑眼圈强度*/
|
||||
faceBeautyData.removePouchIntensity = faceBeauty.getRemovePouchIntensity();
|
||||
/* 去法令纹强度*/
|
||||
faceBeautyData.removeLawPatternIntensity = faceBeauty.getRemoveLawPatternIntensity();
|
||||
|
||||
/* 美型 */
|
||||
/* 瘦脸程度 */
|
||||
faceBeautyData.cheekThinningIntensity = faceBeauty.getCheekThinningIntensity();
|
||||
/* V脸程度 */
|
||||
faceBeautyData.cheekVIntensity = faceBeauty.getCheekVIntensity();
|
||||
/* 窄脸程度 */
|
||||
faceBeautyData.cheekNarrowIntensity = faceBeauty.getCheekNarrowIntensity();
|
||||
/* 短脸程度 */
|
||||
faceBeautyData.cheekShortIntensity = faceBeauty.getCheekShortIntensity();
|
||||
/* 小脸程度 */
|
||||
faceBeautyData.cheekSmallIntensity = faceBeauty.getCheekSmallIntensity();
|
||||
/* 瘦颧骨 */
|
||||
faceBeautyData.cheekBonesIntensity = faceBeauty.getCheekBonesIntensity();
|
||||
/* 瘦下颌骨 */
|
||||
faceBeautyData.lowerJawIntensity = faceBeauty.getLowerJawIntensity();
|
||||
/* 大眼程度 */
|
||||
faceBeautyData.eyeEnlargingIntensity = faceBeauty.getEyeEnlargingIntensity();
|
||||
/* 圆眼程度 */
|
||||
faceBeautyData.eyeCircleIntensity = faceBeauty.getEyeCircleIntensity();
|
||||
/* 下巴调整程度 */
|
||||
faceBeautyData.chinIntensity = faceBeauty.getChinIntensity();
|
||||
/* 额头调整程度 */
|
||||
faceBeautyData.forHeadIntensity = faceBeauty.getForHeadIntensity();
|
||||
/* 瘦鼻程度 */
|
||||
faceBeautyData.noseIntensity = faceBeauty.getNoseIntensity();
|
||||
/* 嘴巴调整程度 */
|
||||
faceBeautyData.mouthIntensity = faceBeauty.getMouthIntensity();
|
||||
/* 开眼角强度 */
|
||||
faceBeautyData.canthusIntensity = faceBeauty.getCanthusIntensity();
|
||||
/* 眼睛间距 */
|
||||
faceBeautyData.eyeSpaceIntensity = faceBeauty.getEyeSpaceIntensity();
|
||||
/* 眼睛角度 */
|
||||
faceBeautyData.eyeRotateIntensity = faceBeauty.getEyeRotateIntensity();
|
||||
/* 鼻子长度 */
|
||||
faceBeautyData.longNoseIntensity = faceBeauty.getLongNoseIntensity();
|
||||
/* 调节人中 */
|
||||
faceBeautyData.philtrumIntensity = faceBeauty.getPhiltrumIntensity();
|
||||
/* 微笑嘴角强度 */
|
||||
faceBeautyData.smileIntensity = faceBeauty.getSmileIntensity();
|
||||
/* 眉毛上下 */
|
||||
faceBeautyData.browHeightIntensity = faceBeauty.getBrowHeightIntensity();
|
||||
/* 眉毛间距 */
|
||||
faceBeautyData.browSpaceIntensity = faceBeauty.getBrowSpaceIntensity();
|
||||
|
||||
/* 滤镜相关 */
|
||||
if (filterList != null) {
|
||||
for (FaceBeautyFilterBean filterBean:filterList) {
|
||||
faceBeautyData.filterMap.put(filterBean.getKey(),filterBean.getIntensity());
|
||||
}
|
||||
}
|
||||
/* 滤镜名称 */
|
||||
faceBeautyData.filterName = faceBeauty.getFilterName();
|
||||
/* 滤镜强度 */
|
||||
faceBeautyData.filterIntensity = faceBeauty.getFilterIntensity();
|
||||
|
||||
/* 是否开启风格 */
|
||||
faceBeautyData.styleTypeIndex = styleTypeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将FaceBeauty 转 FaceBeautyData
|
||||
*
|
||||
* @param faceBeautyData
|
||||
*/
|
||||
public static boolean setFaceBeauty(FaceBeautyData faceBeautyData ,FaceBeauty faceBeauty) {
|
||||
if (faceBeautyData == null) {
|
||||
return false;
|
||||
}
|
||||
if (faceBeauty != null) {
|
||||
/* 如果用户开启了风格推荐 */
|
||||
//下面是否则
|
||||
/* 美肤 */
|
||||
/* 磨皮类型 */
|
||||
if (faceBeautyData.blurType != faceBeauty.getBlurType())
|
||||
faceBeauty.setBlurType(faceBeautyData.blurType);
|
||||
/* 磨皮程度 */
|
||||
if (faceBeautyData.blurIntensity != faceBeauty.getBlurIntensity())
|
||||
faceBeauty.setBlurIntensity(faceBeautyData.blurIntensity);
|
||||
/* 美白程度 */
|
||||
if (faceBeautyData.colorIntensity != faceBeauty.getColorIntensity())
|
||||
faceBeauty.setColorIntensity(faceBeautyData.colorIntensity);
|
||||
/* 红润程度 */
|
||||
if (faceBeautyData.redIntensity != faceBeauty.getRedIntensity())
|
||||
faceBeauty.setRedIntensity(faceBeautyData.redIntensity);
|
||||
/* 锐化程度 */
|
||||
if (faceBeautyData.sharpenIntensity != faceBeauty.getSharpenIntensity())
|
||||
faceBeauty.setSharpenIntensity(faceBeautyData.sharpenIntensity);
|
||||
/* 亮眼程度 */
|
||||
if (faceBeautyData.eyeBrightIntensity != faceBeauty.getEyeBrightIntensity())
|
||||
faceBeauty.setEyeBrightIntensity(faceBeautyData.eyeBrightIntensity);
|
||||
/* 美牙程度 */
|
||||
if (faceBeautyData.toothIntensity != faceBeauty.getToothIntensity())
|
||||
faceBeauty.setToothIntensity(faceBeautyData.toothIntensity);
|
||||
/* 去黑眼圈强度*/
|
||||
if (faceBeautyData.removePouchIntensity != faceBeauty.getRemovePouchIntensity())
|
||||
faceBeauty.setRemovePouchIntensity(faceBeautyData.removePouchIntensity);
|
||||
/* 去法令纹强度*/
|
||||
if (faceBeautyData.removeLawPatternIntensity != faceBeauty.getRemoveLawPatternIntensity())
|
||||
faceBeauty.setRemoveLawPatternIntensity(faceBeautyData.removeLawPatternIntensity);
|
||||
|
||||
/* 美型 */
|
||||
/* 瘦脸程度 */
|
||||
if (faceBeautyData.cheekThinningIntensity != faceBeauty.getCheekThinningIntensity())
|
||||
faceBeauty.setCheekThinningIntensity(faceBeautyData.cheekThinningIntensity);
|
||||
/* V脸程度 */
|
||||
if (faceBeautyData.cheekVIntensity != faceBeauty.getCheekVIntensity())
|
||||
faceBeauty.setCheekVIntensity(faceBeautyData.cheekVIntensity);
|
||||
/* 窄脸程度 */
|
||||
/* V脸程度 */
|
||||
if (faceBeautyData.cheekNarrowIntensity != faceBeauty.getCheekNarrowIntensity())
|
||||
faceBeauty.setCheekNarrowIntensity(faceBeautyData.cheekNarrowIntensity);
|
||||
/* 短脸程度 */
|
||||
if (faceBeautyData.cheekShortIntensity != faceBeauty.getCheekShortIntensity())
|
||||
faceBeauty.setCheekShortIntensity(faceBeautyData.cheekShortIntensity);
|
||||
/* 小脸程度 */
|
||||
if (faceBeautyData.cheekSmallIntensity != faceBeauty.getCheekSmallIntensity())
|
||||
faceBeauty.setCheekSmallIntensity(faceBeautyData.cheekSmallIntensity);
|
||||
/* 瘦颧骨 */
|
||||
if (faceBeautyData.cheekBonesIntensity != faceBeauty.getCheekBonesIntensity())
|
||||
faceBeauty.setCheekBonesIntensity(faceBeautyData.cheekBonesIntensity);
|
||||
/* 瘦下颌骨 */
|
||||
if (faceBeautyData.lowerJawIntensity != faceBeauty.getLowerJawIntensity())
|
||||
faceBeauty.setLowerJawIntensity(faceBeautyData.lowerJawIntensity);
|
||||
/* 大眼程度 */
|
||||
if (faceBeautyData.eyeEnlargingIntensity != faceBeauty.getEyeEnlargingIntensity())
|
||||
faceBeauty.setEyeEnlargingIntensity(faceBeautyData.eyeEnlargingIntensity);
|
||||
/* 圆眼程度 */
|
||||
if (faceBeautyData.eyeCircleIntensity != faceBeauty.getEyeCircleIntensity())
|
||||
faceBeauty.setEyeCircleIntensity(faceBeautyData.eyeCircleIntensity);
|
||||
/* 下巴调整程度 */
|
||||
if (faceBeautyData.chinIntensity != faceBeauty.getChinIntensity())
|
||||
faceBeauty.setChinIntensity(faceBeautyData.chinIntensity);
|
||||
/* 额头调整程度 */
|
||||
if (faceBeautyData.forHeadIntensity != faceBeauty.getForHeadIntensity())
|
||||
faceBeauty.setForHeadIntensity(faceBeautyData.forHeadIntensity);
|
||||
/* 瘦鼻程度 */
|
||||
if (faceBeautyData.noseIntensity != faceBeauty.getNoseIntensity())
|
||||
faceBeauty.setNoseIntensity(faceBeautyData.noseIntensity);
|
||||
/* 嘴巴调整程度 */
|
||||
if (faceBeautyData.mouthIntensity != faceBeauty.getMouthIntensity())
|
||||
faceBeauty.setMouthIntensity(faceBeautyData.mouthIntensity);
|
||||
/* 开眼角强度 */
|
||||
if (faceBeautyData.canthusIntensity != faceBeauty.getCanthusIntensity())
|
||||
faceBeauty.setCanthusIntensity(faceBeautyData.canthusIntensity);
|
||||
/* 眼睛间距 */
|
||||
if (faceBeautyData.eyeSpaceIntensity != faceBeauty.getEyeSpaceIntensity())
|
||||
faceBeauty.setEyeSpaceIntensity(faceBeautyData.eyeSpaceIntensity);
|
||||
/* 眼睛角度 */
|
||||
if (faceBeautyData.eyeRotateIntensity != faceBeauty.getEyeRotateIntensity())
|
||||
faceBeauty.setEyeRotateIntensity(faceBeautyData.eyeRotateIntensity);
|
||||
/* 鼻子长度 */
|
||||
if (faceBeautyData.longNoseIntensity != faceBeauty.getLongNoseIntensity())
|
||||
faceBeauty.setLongNoseIntensity(faceBeautyData.longNoseIntensity);
|
||||
/* 调节人中 */
|
||||
if (faceBeautyData.philtrumIntensity != faceBeauty.getPhiltrumIntensity())
|
||||
faceBeauty.setPhiltrumIntensity(faceBeautyData.philtrumIntensity);
|
||||
/* 微笑嘴角强度 */
|
||||
if (faceBeautyData.smileIntensity != faceBeauty.getSmileIntensity())
|
||||
faceBeauty.setSmileIntensity(faceBeautyData.smileIntensity);
|
||||
/* 眉毛上下 */
|
||||
if (faceBeautyData.browHeightIntensity != faceBeauty.getBrowHeightIntensity())
|
||||
faceBeauty.setBrowHeightIntensity(faceBeautyData.browHeightIntensity);
|
||||
/* 眉毛间距 */
|
||||
if (faceBeautyData.browSpaceIntensity != faceBeauty.getBrowSpaceIntensity())
|
||||
faceBeauty.setBrowSpaceIntensity(faceBeautyData.browSpaceIntensity);
|
||||
|
||||
/* 滤镜相关 */
|
||||
/* 滤镜名称 */
|
||||
if (!faceBeautyData.filterName.equals(faceBeauty.getFilterName()))
|
||||
faceBeauty.setFilterName(faceBeautyData.filterName);
|
||||
if (faceBeautyData.filterIntensity != faceBeauty.getFilterIntensity())
|
||||
faceBeauty.setFilterIntensity(faceBeautyData.filterIntensity);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将FaceBeautyData保存到文件
|
||||
*
|
||||
* @param faceBeautyData
|
||||
*/
|
||||
public static void saveFaceBeautyData2File(FaceBeautyData faceBeautyData, FaceBeauty faceBeauty, ArrayList<FaceBeautyFilterBean> filterList, int styleTypeIndex) {
|
||||
buildFaceBeautyData(faceBeautyData,faceBeauty,filterList,styleTypeIndex);
|
||||
saveFaceBeautyData2File(faceBeautyData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将FaceBeautyData保存到文件
|
||||
*
|
||||
* @param faceBeautyData
|
||||
*/
|
||||
public static void saveFaceBeautyData2File(FaceBeautyData faceBeautyData) {
|
||||
Gson gson = new Gson();
|
||||
String faceBeautyString = gson.toJson(faceBeautyData);
|
||||
saveToSp(SP_KEY_NAME, faceBeautyString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取bean对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static FaceBeautyData loadFaceBeautyData() {
|
||||
String faceBeautyData = loadFormSp(SP_KEY_NAME);
|
||||
if (faceBeautyData != null && !faceBeautyData.isEmpty()) {
|
||||
Gson gson = new Gson();
|
||||
FaceBeautyData faceBeautyDataBean = gson.fromJson(faceBeautyData, FaceBeautyData.class);
|
||||
return faceBeautyDataBean;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void saveToSp(String key, String value) {
|
||||
SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
||||
sp.edit().putString(key, value).apply();
|
||||
}
|
||||
|
||||
private static String loadFormSp(String key) {
|
||||
SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
||||
return sp.getString(key, "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.yunbao.faceunity.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import com.yunbao.common.CommonAppContext;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class FaceSPUtils {
|
||||
private static FaceSPUtils utils;
|
||||
private SharedPreferences mSharedPreferences;
|
||||
private FaceSPUtils(){
|
||||
mSharedPreferences = CommonAppContext.sInstance.getSharedPreferences("FaceUnityConfig", Context.MODE_PRIVATE);
|
||||
}
|
||||
public static FaceSPUtils getInstance(){
|
||||
if(utils==null){
|
||||
utils=new FaceSPUtils();
|
||||
}
|
||||
return utils;
|
||||
}
|
||||
public void saveString(String key,String value){
|
||||
mSharedPreferences.edit().putString(key,value).apply();
|
||||
}
|
||||
public String getString(String key){
|
||||
return mSharedPreferences.getString(key,null);
|
||||
}
|
||||
public boolean saveBool(String key,boolean value){
|
||||
return mSharedPreferences.getBoolean(key,false);
|
||||
}
|
||||
|
||||
public void del(String key) {
|
||||
mSharedPreferences.edit().remove(key).apply();
|
||||
}
|
||||
|
||||
public void delStart(String key){
|
||||
for (String _key : mSharedPreferences.getAll().keySet()) {
|
||||
if(_key.startsWith(key)){
|
||||
mSharedPreferences.edit().remove(key).apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
public Map<String, ?> getAll(){
|
||||
return mSharedPreferences.getAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.yunbao.faceunity.utils;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.Environment;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 一些配置参数
|
||||
* DESC:
|
||||
* Created on 2021/3/1
|
||||
*/
|
||||
public class FaceUnityConfig {
|
||||
|
||||
/************************** 算法Model ******************************/
|
||||
// 人脸识别
|
||||
public static String BUNDLE_AI_FACE = "model" + File.separator + "ai_face_processor.bundle";
|
||||
// 手势
|
||||
public static String BUNDLE_AI_HAND = "model" + File.separator + "ai_hand_processor.bundle";
|
||||
|
||||
//获取人体bundle
|
||||
public static String getAIHumanBundle() {
|
||||
if (FaceUnityConfig.DEVICE_LEVEL > FuDeviceUtils.DEVICE_LEVEL_MID)
|
||||
return BUNDLE_AI_HUMAN_GPU;
|
||||
else
|
||||
return BUNDLE_AI_HUMAN;
|
||||
}
|
||||
|
||||
// 人体
|
||||
public static String BUNDLE_AI_HUMAN = "model" + File.separator + "ai_human_processor.bundle";
|
||||
// 人体
|
||||
public static String BUNDLE_AI_HUMAN_GPU = "model" + File.separator + "ai_human_processor_gpu.bundle";
|
||||
// 头发
|
||||
public static String BUNDLE_AI_HAIR_SEG = "model" + File.separator + "ai_hairseg.bundle";
|
||||
// 舌头
|
||||
public static String BUNDLE_AI_TONGUE = "graphics" + File.separator + "tongue.bundle";
|
||||
|
||||
/************************** 业务道具存储 ******************************/
|
||||
// 美颜
|
||||
public static String BUNDLE_FACE_BEAUTIFICATION = "graphics" + File.separator + "face_beautification.bundle";
|
||||
|
||||
// 美妆
|
||||
public static String BUNDLE_FACE_MAKEUP = "graphics" + File.separator + "face_makeup.bundle";
|
||||
// 美妆根目录
|
||||
private static String MAKEUP_RESOURCE_DIR = "makeup" + File.separator;
|
||||
//美妆单项颜色组合文件
|
||||
public static String MAKEUP_RESOURCE_COLOR_SETUP_JSON = MAKEUP_RESOURCE_DIR + "color_setup.json";
|
||||
// 美妆参数配置文件目录
|
||||
public static String MAKEUP_RESOURCE_JSON_DIR = MAKEUP_RESOURCE_DIR + "config_json" + File.separator;
|
||||
//美妆组合妆句柄文件目录
|
||||
public static String MAKEUP_RESOURCE_COMBINATION_BUNDLE_DIR = MAKEUP_RESOURCE_DIR + "combination_bundle" + File.separator;//
|
||||
//美妆妆容单项句柄文件目录
|
||||
public static String MAKEUP_RESOURCE_ITEM_BUNDLE_DIR = MAKEUP_RESOURCE_DIR + "item_bundle" + File.separator;
|
||||
|
||||
// 美体
|
||||
public static String BUNDLE_BODY_BEAUTY = "graphics" + File.separator + "body_slim.bundle";
|
||||
|
||||
//动漫滤镜
|
||||
public static String BUNDLE_ANIMATION_FILTER = "graphics" + File.separator + "fuzzytoonfilter.bundle";
|
||||
|
||||
// 美发正常色
|
||||
public static String BUNDLE_HAIR_NORMAL = "hair_seg" + File.separator + "hair_normal.bundle";
|
||||
// 美发渐变色
|
||||
public static String BUNDLE_HAIR_GRADIENT = "hair_seg" + File.separator + "hair_gradient.bundle";
|
||||
// 轻美妆
|
||||
public static String BUNDLE_LIGHT_MAKEUP = "light_makeup" + File.separator + "light_makeup.bundle";
|
||||
|
||||
// 海报换脸
|
||||
public static String BUNDLE_POSTER_CHANGE_FACE = "change_face" + File.separator + "change_face.bundle";
|
||||
|
||||
// 绿幕抠像
|
||||
public static String BUNDLE_BG_SEG_GREEN = "bg_seg_green" + File.separator + "green_screen.bundle";
|
||||
|
||||
// 3D抗锯齿
|
||||
public static String BUNDLE_ANTI_ALIASING = "graphics" + File.separator + "fxaa.bundle";
|
||||
|
||||
// 人像分割
|
||||
public static String BUNDLE_BG_SEG_CUSTOM = "effect" + File.separator + "segment" + File.separator + "bg_segment.bundle";
|
||||
|
||||
//mask bundle
|
||||
public static String BUNDLE_LANDMARKS = "effect" + File.separator + "landmarks.bundle";
|
||||
|
||||
//设备等级默认为中级
|
||||
public static int DEVICE_LEVEL = FuDeviceUtils.DEVICE_LEVEL_HIGH;
|
||||
|
||||
//人脸置信度 标准
|
||||
public static float FACE_CONFIDENCE_SCORE = 0.95f;
|
||||
|
||||
//测试使用 -> 是否开启人脸点位,目前仅在美颜,美妆 情况下使用
|
||||
public static boolean IS_OPEN_LAND_MARK = false;
|
||||
|
||||
//设备名称
|
||||
public static String DEVICE_NAME = "";
|
||||
|
||||
//是否开启日志重定向到文件
|
||||
public static boolean OPEN_FILE_LOG = false;
|
||||
//TAG
|
||||
public static final String APP_NAME = "KotlinFaceUnityDemo";
|
||||
//文件夹路径
|
||||
public static String OPEN_FILE_PATH = Environment.getExternalStoragePublicDirectory("") + File.separator + "FaceUnity" + File.separator + APP_NAME + File.separator;
|
||||
//文件夹名称
|
||||
public static String OPEN_FILE_NAME = "openFile.txt";
|
||||
//文件大小
|
||||
public static int OPEN_FILE_MAX_SIZE = 100 * 1024 * 1024;
|
||||
//文件数量
|
||||
public static int OPEN_FILES = 100;
|
||||
|
||||
//timeProfile是否开启
|
||||
public static boolean OPEN_TIME_PROFILE_LOG = false;
|
||||
//timeProfile文件夹路径
|
||||
public static String OPEN_TIME_PROFILE_PATH = Environment.getExternalStoragePublicDirectory("") + File.separator + "FaceUnity" + File.separator + APP_NAME + File.separator;
|
||||
|
||||
//是否开启美颜序列化到磁盘
|
||||
public static boolean OPEN_FACE_BEAUTY_TO_FILE = true;
|
||||
|
||||
//获取缓存路径
|
||||
public static String cacheFilePath(Application application){
|
||||
return application.getCacheDir() + File.separator + "attribute";
|
||||
}
|
||||
|
||||
//绿幕背景切换的时候跳过的帧数
|
||||
public static final int BG_GREEN_FILTER_FRAME = 1;
|
||||
|
||||
//测试用是否展示效果还原按钮
|
||||
public static final boolean IS_SHOW_RESET_BUTTON = false;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user