diff --git a/OpenNSFW/src/main/AndroidManifest.xml b/OpenNSFW/src/main/AndroidManifest.xml index 79cf2019..1b8cb6c5 100644 --- a/OpenNSFW/src/main/AndroidManifest.xml +++ b/OpenNSFW/src/main/AndroidManifest.xml @@ -1,2 +1 @@ - + diff --git a/README.md b/README.md index 5e73bae7..85c3e4f5 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,11 @@ ### JavaScript参考[JS相关文档](https://js.tensorflow.org/api/latest/) >>> 其中Python、C++均有两种数据喂入的方式,可根据需求选择pb模型或tfLite文件,详细请参考上面的链接.Java的目前只能加载pb模型。其他的平台可自行[百度](https://www.baidu.com) ### [pb模型下载](https://github.com/devzwy/NSFW-Python/tree/master/model) -### 本项目移除测试图片,请下载Demo后自行配图测试 +### 本项目移除测试图片,请下载Demo后自行配图测试 +#### 即将优化Demo使用MVVM模式,可用作开发脚手架使用 +`Kotlin+okhttp3+rxjava2+retrofit2+koin+glide+greendao+databinding+Livedata` + +![MVVM](https://github.com/devzwy/open_nsfw_android/blob/dev/img/3.jpeg) ### 使用 - Add it in your root build.gradle at the end of repositories: diff --git a/app/build.gradle b/app/build.gradle index 78bc1aac..ef5e31da 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -58,4 +58,8 @@ dependencies { // implementation project(path: ':nsfw') // implementation project(path: ':OpenNSFW') implementation 'com.github.devzwy:open_nsfw_android:1.3.0' + + implementation 'com.squareup.okhttp3:okhttp:4.7.2' + implementation "org.koin:koin-android:2.1.5" + implementation 'com.google.code.gson:gson:2.8.6' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2dc38f43..a9ae5727 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,32 +1,34 @@ + package="com.example.open_nsfw_android"> - - - - + + + + + android:label="@string/title_activity_main2" /> - + - + - + \ No newline at end of file diff --git a/app/src/main/java/com/example/open_nsfw_android/DemoApplication.kt b/app/src/main/java/com/example/open_nsfw_android/DemoApplication.kt index 5c8f58b8..9886c340 100644 --- a/app/src/main/java/com/example/open_nsfw_android/DemoApplication.kt +++ b/app/src/main/java/com/example/open_nsfw_android/DemoApplication.kt @@ -1,15 +1,32 @@ package com.example.open_nsfw_android import android.app.Application +import com.example.open_nsfw_android.view.mModules import com.zwy.opennsfw.core.Classifier +import okhttp3.OkHttp +import okhttp3.OkHttpClient +import okhttp3.Request +import org.koin.android.ext.koin.androidContext +import org.koin.android.ext.koin.androidFileProperties +import org.koin.android.ext.koin.androidLogger +import org.koin.core.context.startKoin +import org.koin.core.logger.PrintLogger +import org.koin.core.qualifier.qualifier +import org.koin.dsl.module class DemoApplication : Application() { override fun onCreate() { super.onCreate() + + startKoin { + modules(mModules) + } Classifier.Build() .context(this) //必须调用 否则会有异常抛出 // .isOpenGPU(true)//默认不开启GPU加速 部分机型开启会奔溃,自行选择,默认false // .numThreads(10) //分配的线程数 根据手机配置设置,默认1 .build() + } -} \ No newline at end of file + +} diff --git a/app/src/main/java/com/example/open_nsfw_android/util/MainAdapter.kt b/app/src/main/java/com/example/open_nsfw_android/util/MainAdapter.kt index 148beaa3..73b85ed7 100644 --- a/app/src/main/java/com/example/open_nsfw_android/util/MainAdapter.kt +++ b/app/src/main/java/com/example/open_nsfw_android/util/MainAdapter.kt @@ -5,9 +5,12 @@ import android.support.v4.content.ContextCompat import android.widget.ImageView import android.widget.RelativeLayout import android.widget.TextView +import com.bumptech.glide.Glide import com.chad.library.adapter.base.BaseQuickAdapter import com.chad.library.adapter.base.BaseViewHolder import com.example.open_nsfw_android.R +import getNsfwScore +import kotlinx.android.synthetic.main.activity_main2.* import java.math.RoundingMode import java.text.DecimalFormat @@ -15,12 +18,14 @@ class MainAdapter(nsfwList: List?) : BaseQuickAdapter(R.layout.main_item, nsfwList) { @SuppressLint("SetTextI18n") - override fun convert(helper: BaseViewHolder, item: MyNsfwBean) { + override fun convert(helper: BaseViewHolder, item2: MyNsfwBean) { + val textView = helper.getView(R.id.tv_text) val imageView = helper.getView(R.id.iv) val view = helper.getView(R.id.view) + var color = ContextCompat.getColor(mContext, R.color.nsfw1) - when (item.nsfw) { + when (item2.nsfw) { in 0.0..0.2 -> { color = ContextCompat.getColor(mContext, R.color.nsfw3) } @@ -33,8 +38,14 @@ class MainAdapter(nsfwList: List?) : floatFormat.roundingMode = RoundingMode.HALF_UP textView.text = - "\n适宜度(非色情程度):${floatFormat.format(item.sfw * 100)}%\n\n不适宜度(涉黄程度):${floatFormat.format(item.nsfw * 100)}%" - imageView.setImageBitmap(item.bitmap) + "\n适宜度(非色情程度):${floatFormat.format(item2.sfw * 100)}%\n\n不适宜度(涉黄程度):${floatFormat.format( + item2.nsfw * 100 + )}%" + if (item2.imgUrl != null && item2.imgUrl.isNotBlank()) { + Glide.with(imageView).load(item2.imgUrl).into(imageView) + } else { + imageView.setImageBitmap(item2.bitmap) + } view.setBackgroundColor(color) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/open_nsfw_android/util/kt.kt b/app/src/main/java/com/example/open_nsfw_android/util/kt.kt index c9855c57..2d19ba2b 100644 --- a/app/src/main/java/com/example/open_nsfw_android/util/kt.kt +++ b/app/src/main/java/com/example/open_nsfw_android/util/kt.kt @@ -2,4 +2,10 @@ package com.example.open_nsfw_android.util import android.graphics.Bitmap -data class MyNsfwBean(var sfw: Float, var nsfw: Float, val path: String, val bitmap: Bitmap) \ No newline at end of file +data class MyNsfwBean( + var sfw: Float, + var nsfw: Float, + val path: String, + val bitmap: Bitmap?, + val imgUrl: String? = "" +) \ No newline at end of file diff --git a/app/src/main/java/com/example/open_nsfw_android/view/CameraActivity.kt b/app/src/main/java/com/example/open_nsfw_android/view/CameraActivity.kt index 6a86339c..8e8508fd 100644 --- a/app/src/main/java/com/example/open_nsfw_android/view/CameraActivity.kt +++ b/app/src/main/java/com/example/open_nsfw_android/view/CameraActivity.kt @@ -182,17 +182,17 @@ class CameraActivity : AppCompatActivity(), SurfaceHolder.Callback, Camera.Previ @SuppressLint("SetTextI18n") override fun onPreviewFrame(data: ByteArray?, camera: Camera?) { - mCamera.addCallbackBuffer(data) - - val size = mCamera.parameters.previewSize; - val image = YuvImage(data, ImageFormat.NV21, size.width, size.height, null); - val stream = ByteArrayOutputStream() - image.compressToJpeg(Rect(0, 0, size.width, size.height), 80, stream) - val bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size()) - bmp.getNsfwScore() - val spText = bmp.getNsfwScore().toString().split(",") - textView.text = spText[0] + "\n" + spText[1] - stream.close() + mCamera.addCallbackBuffer(data) + + val size = mCamera.parameters.previewSize; + val image = YuvImage(data, ImageFormat.NV21, size.width, size.height, null); + val stream = ByteArrayOutputStream() + image.compressToJpeg(Rect(0, 0, size.width, size.height), 80, stream) + val bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size()) + bmp.getNsfwScore() + val spText = bmp.getNsfwScore().toString().split(",") + textView.text = spText[0] + "\n" + spText[1] + stream.close() } } \ No newline at end of file diff --git a/app/src/main/java/com/example/open_nsfw_android/view/MainAty.kt b/app/src/main/java/com/example/open_nsfw_android/view/MainAty.kt index f39972c5..bd0f0ecf 100644 --- a/app/src/main/java/com/example/open_nsfw_android/view/MainAty.kt +++ b/app/src/main/java/com/example/open_nsfw_android/view/MainAty.kt @@ -5,24 +5,30 @@ import android.annotation.SuppressLint import android.content.Intent import android.content.pm.PackageManager import android.graphics.BitmapFactory -import android.graphics.Camera import android.os.Bundle import android.support.v4.app.ActivityCompat import android.support.v4.content.ContextCompat import android.support.v7.app.AppCompatActivity import android.support.v7.widget.LinearLayoutManager import android.widget.Toast +import com.bumptech.glide.Glide import com.example.open_nsfw_android.R import com.example.open_nsfw_android.util.MainAdapter import com.example.open_nsfw_android.util.MyNsfwBean import com.example.open_nsfw_android.util.PackageUtils +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.luck.picture.lib.PictureSelector import com.luck.picture.lib.config.PictureConfig import com.luck.picture.lib.config.PictureMimeType import com.luck.picture.lib.entity.LocalMedia import getNsfwScore import kotlinx.android.synthetic.main.activity_main.* +import okhttp3.* +import org.koin.android.ext.android.inject import java.io.File +import java.io.IOException +import java.lang.reflect.Type class MainAty : AppCompatActivity() { @@ -30,6 +36,11 @@ class MainAty : AppCompatActivity() { lateinit var mMainAdapter: MainAdapter + val httpClient: OkHttpClient by inject() + + val gson: Gson by inject() + + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) @@ -48,11 +59,62 @@ class MainAty : AppCompatActivity() { //识别assets目录 bt_sc_assets.setOnClickListener { assetsListSc() } //选择相册进行扫描 - bt_sc_from_other.setOnClickListener { selectImgFromD() } + bt_sc_from_other.setOnClickListener { selectImgFromD(0x01) } //跳转网络图片识别页面 - bt_sc_from_internet.setOnClickListener { startActivity(Intent(this, Main2Activity::class.java)) } + bt_sc_from_internet.setOnClickListener { + startActivity( + Intent( + this, + Main2Activity::class.java + ) + ) + } //实时扫描 bt_sc_from_cam.setOnClickListener { scCamera() } + //调用Api获取测试图片 + bt_sc_from_api.setOnClickListener { + httpClient.newCall(Request.Builder().get().url(GetImageListURL).build()) + .enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + runOnUiThread { + Toast.makeText(this@MainAty, "请求失败,请重试", Toast.LENGTH_SHORT).show() + } + } + + override fun onResponse(call: Call, response: Response) { + val str = response.body?.string() + val type: Type? = object : TypeToken>() {}.type + val list = gson.fromJson>(str, type) + val l = ArrayList() + //迭代数据并获取涉黄程度 + list.forEach { + System.out.println(it) + val file = Glide.with(this@MainAty) + .load(it.imgUrl) + .downloadOnly(120, 120).get() + val nsfwBean = file.getNsfwScore() + //填充数据到适配器 + l.add( + MyNsfwBean( + sfw = nsfwBean.sfw, + nsfw = nsfwBean.nsfw, + path = it.createTime, + imgUrl = it.imgUrl, + bitmap = null + ) + ) + } + runOnUiThread { + mMainAdapter.setNewData(null) + mMainAdapter.setNewData(l) + } + } + }) + } + + bt_upload.setOnClickListener { + selectImgFromD(0x02) + } tv_version.text = "当前版本号:${PackageUtils.getVersionName(this)}" } @@ -75,7 +137,7 @@ class MainAty : AppCompatActivity() { /** * 相册选择 */ - private fun selectImgFromD() { + private fun selectImgFromD(requestCode: Int) { PictureSelector.create(this) .openGallery(PictureMimeType.ofImage())//全部.ofAll()、图片.、视频.ofVideo()、音频.ofAudio() .maxSelectNum(20)// 最大图片选择数量 int @@ -88,7 +150,7 @@ class MainAty : AppCompatActivity() { .selectionMedia(selectList) .sizeMultiplier(0.5f)// glide 加载图片大小 0~1之间 如设置 .glideOverride()无效 .previewEggs(true)// 预览图片时 是否增强左右滑动图片体验(图片滑动一半即可看到上一张是否选中) true or false - .forResult(0x01);//结果回调onActivityResult code } + .forResult(requestCode);//结果回调onActivityResult code } } /** @@ -127,7 +189,11 @@ class MainAty : AppCompatActivity() { Manifest.permission.WRITE_EXTERNAL_STORAGE ) != PackageManager.PERMISSION_GRANTED ) { - ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1); + ActivityCompat.requestPermissions( + this, + arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), + 1 + ); } if (ContextCompat.checkSelfPermission( @@ -164,6 +230,29 @@ class MainAty : AppCompatActivity() { }).start() } + if (requestCode == 0x02 && resultCode == RESULT_OK) { + selectList = PictureSelector.obtainMultipleResult(data) + val builder = MultipartBody.Builder().setType(MultipartBody.FORM) +// selectList?.let { +// mMainAdapter.setNewData(null) +// Toast.makeText(this, "请稍等...", Toast.LENGTH_LONG).show() +// } +// Thread(Runnable { +// selectList?.forEach { +// val file = File(it.path) +// val nsfwScore = file.getNsfwScore() +// addDataToAdapter( +// MyNsfwBean( +// nsfwScore.sfw, +// nsfwScore.nsfw, +// it.path, +// BitmapFactory.decodeStream(file.inputStream()) +// ) +// ) +// } +// }).start() + + } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/open_nsfw_android/view/kt.kt b/app/src/main/java/com/example/open_nsfw_android/view/kt.kt new file mode 100644 index 00000000..bfae1d67 --- /dev/null +++ b/app/src/main/java/com/example/open_nsfw_android/view/kt.kt @@ -0,0 +1,32 @@ +package com.example.open_nsfw_android.view + +import com.google.gson.Gson +import okhttp3.OkHttpClient +import okhttp3.Request +import org.koin.core.qualifier.qualifier +import org.koin.dsl.module + +val BaseUrl = "http://114.116.213.202:7777/" +val GetImageListURL = "${BaseUrl}imageList.do" +val UploadImageURL = "${BaseUrl}imageList.do" + + +val mModules = module { + single { + OkHttpClient.Builder().build() + } + single { + Gson() + } +} + + +data class NSFWImage( + val createTime: String, + val id: Int, + val imgUrl: String +) { + override fun toString(): String { + return Gson().toJson(this) + } +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml index 5768f2e9..e86fe0a9 100644 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -18,10 +18,10 @@ android:type="linear"> + android:offset="0.0" /> + android:offset="1.0" /> @@ -30,5 +30,5 @@ android:fillType="nonZero" android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z" android:strokeWidth="1" - android:strokeColor="#00000000"/> + android:strokeColor="#00000000" /> diff --git a/app/src/main/res/drawable/ch.xml b/app/src/main/res/drawable/ch.xml index 841bdd4f..144c1d8a 100644 --- a/app/src/main/res/drawable/ch.xml +++ b/app/src/main/res/drawable/ch.xml @@ -1,23 +1,29 @@ - - - - - - - + android:width="108dp" + android:height="108dp" + android:viewportWidth="1148.6849" + android:viewportHeight="1148.6849" + android:tint="#4749FF"> + + + + + + + + - \ No newline at end of file diff --git a/app/src/main/res/drawable/change_background.xml b/app/src/main/res/drawable/change_background.xml index ca3826a4..a5ce813b 100644 --- a/app/src/main/res/drawable/change_background.xml +++ b/app/src/main/res/drawable/change_background.xml @@ -1,74 +1,170 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml index 63cb8d91..b91bca99 100644 --- a/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml +++ b/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml @@ -1,5 +1,11 @@ - - + + diff --git a/app/src/main/res/drawable/ic_camera_black_24dp.xml b/app/src/main/res/drawable/ic_camera_black_24dp.xml index 7a5c6cfb..ac0302eb 100644 --- a/app/src/main/res/drawable/ic_camera_black_24dp.xml +++ b/app/src/main/res/drawable/ic_camera_black_24dp.xml @@ -1,5 +1,11 @@ - - + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml index bb1921d6..e2561079 100644 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -6,165 +6,165 @@ android:viewportHeight="108"> + android:pathData="M0,0h108v108h-108z" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> + android:strokeColor="#33FFFFFF" /> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 700b643e..acbe5d76 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,96 +1,136 @@ + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> - - -