From c66af16d585690bf9167f81f6a7eb503f663ee60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5?= Date: Sun, 3 May 2020 17:47:16 +0800 Subject: [PATCH] =?UTF-8?q?Demo=E5=A2=9E=E5=8A=A0=E5=AE=9E=E6=97=B6?= =?UTF-8?q?=E6=89=AB=E6=8F=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/codeStyles/Project.xml | 3 - app/build.gradle | 2 + app/src/main/AndroidManifest.xml | 3 + app/src/main/change-playstore.png | Bin 0 -> 31030 bytes .../open_nsfw_android/util/PackageUtils.kt | 77 +++++++ .../open_nsfw_android/view/CameraActivity.kt | 188 ++++++++++++++++++ .../example/open_nsfw_android/view/MainAty.kt | 26 +++ app/src/main/res/drawable/ch.xml | 23 +++ .../main/res/drawable/change_background.xml | 74 +++++++ .../res/drawable/ic_arrow_back_black_24dp.xml | 5 + .../res/drawable/ic_camera_black_24dp.xml | 5 + app/src/main/res/layout/activity_main.xml | 21 ++ app/src/main/res/layout/cameraaty.xml | 40 ++++ app/src/main/res/mipmap-anydpi-v26/change.xml | 5 + .../res/mipmap-anydpi-v26/change_round.xml | 5 + app/src/main/res/mipmap-hdpi/change.png | Bin 0 -> 2897 bytes app/src/main/res/mipmap-hdpi/change_round.png | Bin 0 -> 5179 bytes app/src/main/res/mipmap-mdpi/change.png | Bin 0 -> 2052 bytes app/src/main/res/mipmap-mdpi/change_round.png | Bin 0 -> 3020 bytes app/src/main/res/mipmap-xhdpi/change.png | Bin 0 -> 4831 bytes .../main/res/mipmap-xhdpi/change_round.png | Bin 0 -> 7784 bytes app/src/main/res/mipmap-xxhdpi/change.png | Bin 0 -> 7004 bytes .../main/res/mipmap-xxhdpi/change_round.png | Bin 0 -> 11724 bytes app/src/main/res/mipmap-xxxhdpi/change.png | Bin 0 -> 10075 bytes .../main/res/mipmap-xxxhdpi/change_round.png | Bin 0 -> 17211 bytes 25 files changed, 474 insertions(+), 3 deletions(-) create mode 100644 app/src/main/change-playstore.png create mode 100644 app/src/main/java/com/example/open_nsfw_android/util/PackageUtils.kt create mode 100644 app/src/main/java/com/example/open_nsfw_android/view/CameraActivity.kt create mode 100644 app/src/main/res/drawable/ch.xml create mode 100644 app/src/main/res/drawable/change_background.xml create mode 100644 app/src/main/res/drawable/ic_arrow_back_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_camera_black_24dp.xml create mode 100644 app/src/main/res/layout/cameraaty.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/change.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/change_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/change.png create mode 100644 app/src/main/res/mipmap-hdpi/change_round.png create mode 100644 app/src/main/res/mipmap-mdpi/change.png create mode 100644 app/src/main/res/mipmap-mdpi/change_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/change.png create mode 100644 app/src/main/res/mipmap-xhdpi/change_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/change.png create mode 100644 app/src/main/res/mipmap-xxhdpi/change_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/change.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/change_round.png diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index afe97ef6..9624886b 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,8 +1,5 @@ - - diff --git a/app/build.gradle b/app/build.gradle index 77f94b0f..78bc1aac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -53,6 +53,8 @@ dependencies { implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50' implementation 'com.github.LuckSiege.PictureSelector:picture_library:2.2.5' + implementation 'com.camerakit:camerakit:1.0.0-beta3.11' + implementation 'com.camerakit:jpegkit:0.1.0' // implementation project(path: ':nsfw') // implementation project(path: ':OpenNSFW') implementation 'com.github.devzwy:open_nsfw_android:1.3.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b757e8bd..2dc38f43 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ + @@ -24,6 +25,8 @@ + \ No newline at end of file diff --git a/app/src/main/change-playstore.png b/app/src/main/change-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..78877ef67ee3471502b2af183ea81771aabf9d4c GIT binary patch literal 31030 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 B=Sctn literal 0 HcmV?d00001 diff --git a/app/src/main/java/com/example/open_nsfw_android/util/PackageUtils.kt b/app/src/main/java/com/example/open_nsfw_android/util/PackageUtils.kt new file mode 100644 index 00000000..48cd508c --- /dev/null +++ b/app/src/main/java/com/example/open_nsfw_android/util/PackageUtils.kt @@ -0,0 +1,77 @@ +package com.example.open_nsfw_android.util + +import android.content.Context +import android.content.pm.PackageManager + +object PackageUtils { + /** + * 获取版本名称 + * + * @param context 上下文 + * + * @return 版本名称 + */ + fun getVersionName(context: Context): String? { + + //获取包管理器 + val pm = context.packageManager + //获取包信息 + try { + val packageInfo = + pm.getPackageInfo(context.packageName, 0) + //返回版本号 + return packageInfo.versionName + } catch (e: PackageManager.NameNotFoundException) { + e.printStackTrace() + } + return null + } + + /** + * 获取版本号 + * + * @param context 上下文 + * + * @return 版本号 + */ + fun getVersionCode(context: Context): Int { + + //获取包管理器 + val pm = context.packageManager + //获取包信息 + try { + val packageInfo = + pm.getPackageInfo(context.packageName, 0) + //返回版本号 + return packageInfo.versionCode + } catch (e: PackageManager.NameNotFoundException) { + e.printStackTrace() + } + return 0 + } + + /** + * 获取App的名称 + * + * @param context 上下文 + * + * @return 名称 + */ + fun getAppName(context: Context): String? { + val pm = context.packageManager + //获取包信息 + try { + val packageInfo = + pm.getPackageInfo(context.packageName, 0) + //获取应用 信息 + val applicationInfo = packageInfo.applicationInfo + //获取albelRes + val labelRes = applicationInfo.labelRes + //返回App的名称 + return context.resources.getString(labelRes) + } catch (e: PackageManager.NameNotFoundException) { + e.printStackTrace() + } + return null + } +} \ 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 new file mode 100644 index 00000000..ec5dc53c --- /dev/null +++ b/app/src/main/java/com/example/open_nsfw_android/view/CameraActivity.kt @@ -0,0 +1,188 @@ +package com.example.open_nsfw_android.view + +import android.annotation.SuppressLint +import android.graphics.BitmapFactory +import android.graphics.ImageFormat +import android.graphics.Rect +import android.graphics.YuvImage +import android.hardware.Camera +import android.os.Bundle +import android.support.v7.app.AppCompatActivity +import android.view.SurfaceHolder +import android.view.Window +import android.view.WindowManager +import android.widget.Toast +import com.example.open_nsfw_android.R +import getNsfwScore +import kotlinx.android.synthetic.main.cameraaty.* +import java.io.ByteArrayOutputStream +import java.io.IOException +import java.util.* + +class CameraActivity : AppCompatActivity(), SurfaceHolder.Callback, Camera.PreviewCallback { + + lateinit var mSurfaceHolder: SurfaceHolder + lateinit var mCamera: Camera + private var cameraId = 1 + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + requestWindowFeature(Window.FEATURE_NO_TITLE); + window.setFlags( + WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN + ) + setContentView(R.layout.cameraaty) + + mSurfaceHolder = surfaceView.holder + mSurfaceHolder.addCallback(this) + iv_back.setOnClickListener { + try { + mCamera.setPreviewCallback(null) + mCamera.stopPreview() + mCamera.release() + } catch (e: Exception) { + } + finish() + } + } + + //翻转摄像机 + fun cameraSwitch() { + cameraId = if (cameraId == 1) 0 else 1 + mCamera.setPreviewCallback(null) + mCamera.stopPreview() + mCamera.release() + CameraOpen() + } + + + //打开照相机 + fun CameraOpen() { + try { + //打开摄像机 + mCamera = Camera.open(cameraId) + mCamera.setDisplayOrientation(90) + //绑定Surface并开启预览 + mCamera.setPreviewDisplay(mSurfaceHolder) + val parameters = mCamera.parameters +// val focusModes = parameters.supportedFocusModes +// val size = calculatePerfectSize( +// parameters.supportedPreviewSizes, +// 1024, 1024 +// ) +// surfaceView.layoutParams.width = size!!.width +// surfaceView.layoutParams.height = size.height +// +// parameters.setPreviewSize(size.width, size.height) + parameters.focusMode = "fixed" + mCamera.parameters = parameters + mCamera.startPreview() + mCamera.setPreviewCallback(this) + iv_change.setOnClickListener { cameraSwitch() } + } catch (e: IOException) { + mCamera.release() + Toast.makeText(this, "视图创建失败", Toast.LENGTH_SHORT).show() + } + } + + override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) { + val parameters = mCamera.parameters + mCamera.parameters = parameters + mCamera.startPreview() + } + + /** + * 计算最完美的Size + * @param sizes + * @param expectWidth + * @param expectHeight + * @return + */ + fun calculatePerfectSize( + sizes: List, expectWidth: Int, + expectHeight: Int + ): Camera.Size? { + sortList(sizes) // 根据宽度进行排序 + var result = sizes[0] + var widthOrHeight = false // 判断存在宽或高相等的Size + // 辗转计算宽高最接近的值 + for (size in sizes) { + // 如果宽高相等,则直接返回 + if (size.width == expectWidth && size.height == expectHeight) { + result = size + break + } + // 仅仅是宽度相等,计算高度最接近的size + if (size.width == expectWidth) { + widthOrHeight = true + if (Math.abs(result.height - expectHeight) + > Math.abs(size.height - expectHeight) + ) { + result = size + } + } else if (size.height == expectHeight) { + widthOrHeight = true + if (Math.abs(result.width - expectWidth) + > Math.abs(size.width - expectWidth) + ) { + result = size + } + } else if (!widthOrHeight) { + if (Math.abs(result.width - expectWidth) + > Math.abs(size.width - expectWidth) + && Math.abs(result.height - expectHeight) + > Math.abs(size.height - expectHeight) + ) { + result = size + } + } + } + return result + } + + /** + * 排序 + * @param list + */ + private fun sortList(list: List) { + Collections.sort(list, object : Comparator { + + override fun compare(pre: Camera.Size?, after: Camera.Size?): Int { + if (pre!!.width > after!!.width) { + return 1 + } else if (pre.width < after.width) { + return -1 + } + return 0 + } + }) + } + + + override fun surfaceDestroyed(holder: SurfaceHolder?) { + mCamera.stopPreview() + mCamera.release() + } + + + override fun surfaceCreated(holder: SurfaceHolder?) { + CameraOpen() + } + + @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() + } + +} \ 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 6b69ff3d..f39972c5 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 @@ -1,9 +1,11 @@ package com.example.open_nsfw_android.view import android.Manifest +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 @@ -13,6 +15,7 @@ import android.widget.Toast 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.luck.picture.lib.PictureSelector import com.luck.picture.lib.config.PictureConfig import com.luck.picture.lib.config.PictureMimeType @@ -36,6 +39,7 @@ class MainAty : AppCompatActivity() { } + @SuppressLint("SetTextI18n") fun init() { //检测权限 checkPermissions() @@ -47,6 +51,18 @@ class MainAty : AppCompatActivity() { bt_sc_from_other.setOnClickListener { selectImgFromD() } //跳转网络图片识别页面 bt_sc_from_internet.setOnClickListener { startActivity(Intent(this, Main2Activity::class.java)) } + //实时扫描 + bt_sc_from_cam.setOnClickListener { scCamera() } + tv_version.text = "当前版本号:${PackageUtils.getVersionName(this)}" + } + + + /** + * 实时扫描 + */ + private fun scCamera() { + + startActivity(Intent(this, CameraActivity::class.java)) } @@ -97,6 +113,7 @@ class MainAty : AppCompatActivity() { }).start() } + private fun addDataToAdapter(mMyNsfwBean: MyNsfwBean) { runOnUiThread { mMainAdapter.addData(mMyNsfwBean) } } @@ -112,6 +129,15 @@ class MainAty : AppCompatActivity() { ) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1); } + + if (ContextCompat.checkSelfPermission( + this, + Manifest.permission.CAMERA + ) != PackageManager.PERMISSION_GRANTED + ) { + ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 1); + } + } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { diff --git a/app/src/main/res/drawable/ch.xml b/app/src/main/res/drawable/ch.xml new file mode 100644 index 00000000..841bdd4f --- /dev/null +++ b/app/src/main/res/drawable/ch.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + \ 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 new file mode 100644 index 00000000..ca3826a4 --- /dev/null +++ b/app/src/main/res/drawable/change_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 00000000..63cb8d91 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_camera_black_24dp.xml b/app/src/main/res/drawable/ic_camera_black_24dp.xml new file mode 100644 index 00000000..7a5c6cfb --- /dev/null +++ b/app/src/main/res/drawable/ic_camera_black_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 086532fa..700b643e 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -31,6 +31,27 @@ android:padding="15dp" android:text="从相册选取"/> + + + + + + + +