由于一些不可告人的需求,所以開始尋找各種可以實現安卓實時獲得屏幕上某個像素點的功能
首先,將需求進行拆解,分別為
1、獲得屏幕
2、獲得屏幕上一個像素點
獲得屏幕
獲得屏幕分為比較多種的方式,在以前大致分為adb screencap 獲取當前屏幕
linux 底層 通過frameBuffer獲得屏幕信息
我沒試過我也不知道好不好用
參考1
參考2
通過 MediaProjection 屏幕錄制獲得圖像
參考
我使用的是 MediaProject 的方法,這里重點實現了這個方法
由于我的需求是需要處處調用的,所以將獲取像素點的一系列方法封裝在一個單例之中,以達到一處聲明,處處調用package com.tools.automator.core
import android.graphics.Bitmap
import android.app.ActivityManager
import android.content.Context
import android.graphics.PixelFormat
import android.hardware.display.DisplayManager
import android.media.Image
import android.media.ImageReader
import android.media.projection.MediaProjection
import android.util.DisplayMetrics
import android.util.Log
import android.view.WindowManager
import java.nio.ByteBuffer
class Screen private constructor(context: Context){
internal val TAG = "Screen"
var reader:ImageReader? = null;
var bitmap:Bitmap? = null;
var windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager;
// 單利
companion object {
@Volatile private var INSTANCE: Screen? = null;
@Volatile private var mediaProjection:MediaProjection? = null;
fun getInstance(context: Context): Screen =
INSTANCE?: synchronized(this){
INSTANCE?: buildScreen(context).also { INSTANCE = it }
}
fun getInstance():Screen {
return INSTANCE!!
}
// 初始化函數,用于傳入MediaProjection
fun setMedia(mMediaProjection: MediaProjection){
mediaProjection=mMediaProjection
}
// 創建屏幕
private fun buildScreen(context: Context) = Screen(context)
}
// 獲得顏色,RGBColor是一個自己封裝的類,用于返回帶有RGB值的對象
fun getPixelColor(x: Int,y: Int):RGBColor{
return RGBColor(getColor(x,y))
}
// 創建虛擬屏幕
fun setUpVirtualDisplay() {
var dm:DisplayMetrics = DisplayMetrics();
windowManager.defaultDisplay.getRealMetrics(dm)
var imageReader:ImageReader = ImageReader.newInstance(dm.widthPixels, dm.heightPixels, PixelFormat.RGBA_8888, 1);
// 實時獲得屏幕
mediaProjection?.createVirtualDisplay("ScreenCapture",
dm.widthPixels, dm.heightPixels, dm.densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
imageReader.getSurface(), null, null);
reader = imageReader;
}
// 使用BitMap獲得顏色,并返回
internal fun getColor(x:Int, y:Int):Int {
if (reader == null) {
Log.w(TAG, "getColor: reader is null");
return -1;
}
val image:Image? = reader!!.acquireLatestImage();
if (image == null) {
if (bitmap == null) {
Log.w(TAG, "getColor: image is null");
return -1;
}
return bitmap!!.getPixel(x, y);
}
var width:Int = image.getWidth();
var height:Int = image.getHeight();
val planes = image.getPlanes();
val buffer: ByteBuffer = planes[0].getBuffer();
var pixelStride = planes[0].getPixelStride();
var rowStride = planes[0].getRowStride();
var rowPadding = rowStride - pixelStride * width;
if (bitmap == null) {
bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
}
bitmap!!.copyPixelsFromBuffer(buffer);
image.close();
return bitmap!!.getPixel(x, y);
}
}
顏色類package com.tools.automator.core
import android.graphics.Color
class RGBColor{
var red:String;
var green:String;
var blue:String;
var alpha:String;
constructor(color:Int){
red = Color.red(color).toString(16)
blue = Color.blue(color).toString(16)
green = Color.green(color).toString(16)
alpha = Color.alpha(color).toString(16)
}
fun getColor():RGBColor{
return this
}
}
初始化Screen.setMedia(mMediaProjection);
Screen.getInstance(this).setUpVirtualDisplay();