You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需点击屏幕实时获取像素值?实现相机画面实时取像素

解决方案

一、修复现有代码的错误

你当前的代码存在明显的颜色通道获取错误:G、B通道都误用了Color.red(pixel),正确代码如下:

sl.setDrawingCacheEnabled(true);
sl.buildDrawingCache(true);

bitmap = sl.getDrawingCache();
int pixel = bitmap.getPixel((int) 39, (int) 31);

int r = Color.red(pixel);
int g = Color.green(pixel); // 修正为green方法
int b = Color.blue(pixel);  // 修正为blue方法

cl.setText("R("+r+")\nG("+g+")\nB("+b+")");
Log.d("Color Detection: ","R("+r+") "+"G("+g+") "+"B("+b+")"+Tracker.labelString.length());

二、实现无需点击的实时View像素获取

使用DrawingCache无法做到真正的实时更新,推荐通过定时任务结合资源回收机制来周期性获取像素:

实现代码

private Handler handler = new Handler(Looper.getMainLooper());
private Runnable pixelCaptureTask = new Runnable() {
    @Override
    public void run() {
        if (sl != null && sl.isShown()) {
            sl.setDrawingCacheEnabled(true);
            sl.buildDrawingCache(true);
            Bitmap cacheBitmap = sl.getDrawingCache();
            
            if (cacheBitmap != null) {
                int pixel = cacheBitmap.getPixel(39, 31);
                int r = Color.red(pixel);
                int g = Color.green(pixel);
                int b = Color.blue(pixel);
                
                cl.setText(String.format("R(%d)\nG(%d)\nB(%d)", r, g, b));
                cacheBitmap.recycle(); // 释放缓存避免内存泄漏
            }
            
            sl.setDrawingCacheEnabled(false);
        }
        handler.postDelayed(this, 16); // 约60帧/秒,接近实时更新
    }
};

// 在页面恢复时启动任务
@Override
protected void onResume() {
    super.onResume();
    handler.post(pixelCaptureTask);
}

// 在页面暂停时停止任务
@Override
protected void onPause() {
    super.onPause();
    handler.removeCallbacks(pixelCaptureTask);
}

注意事项

  • 频繁创建绘制缓存可能引发内存问题,务必在使用后禁用缓存并回收Bitmap。
  • 若View内容变化频繁,可监听ViewTreeObserver.OnDrawListener,在View绘制完成后立即获取像素。

三、从相机画面实时获取像素值

要实现类似你提供的示例中的相机实时取色功能,推荐使用CameraX(Android Jetpack组件,兼容性更强):

步骤1:添加依赖

在build.gradle的dependencies块中加入:

def camerax_version = "1.3.0"
implementation "androidx.camera:camera-core:$camerax_version"
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:$camerax_version"

步骤2:布局添加预览组件

<androidx.camera.view.PreviewView
    android:id="@+id/previewView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<TextView
    android:id="@+id/colorInfo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#CC000000"
    android:textColor="#FFFFFF"
    android:padding="8dp"
    android:layout_gravity="bottom|start"/>

步骤3:实现帧分析逻辑

private PreviewView previewView;
private TextView colorInfo;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camera);
    previewView = findViewById(R.id.previewView);
    colorInfo = findViewById(R.id.colorInfo);
    
    // 启动相机
    startCamera();
}

private void startCamera() {
    // 配置预览用例
    Preview preview = new Preview.Builder().build();
    preview.setSurfaceProvider(previewView.getSurfaceProvider());

    // 配置实时帧分析用例
    ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) // 只处理最新帧
            .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
            .build();

    imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor(), image -> {
        // 获取帧像素数据
        ImageProxy.PlaneProxy plane = image.getPlanes()[0];
        ByteBuffer buffer = plane.getBuffer();
        byte[] data = new byte[buffer.remaining()];
        buffer.get(data);

        // 转换为Bitmap
        Bitmap frameBitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
        frameBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(data));

        // 获取画面中心像素(可替换为你需要的坐标)
        int targetX = image.getWidth() / 2;
        int targetY = image.getHeight() / 2;
        int pixel = frameBitmap.getPixel(targetX, targetY);
        int r = Color.red(pixel);
        int g = Color.green(pixel);
        int b = Color.blue(pixel);

        // 回到主线程更新UI
        runOnUiThread(() -> {
            colorInfo.setText(String.format("R:%d\nG:%d\nB:%d", r, g, b));
        });

        // 必须关闭ImageProxy,否则会阻塞后续帧
        image.close();
        frameBitmap.recycle();
    });

    // 绑定相机与页面生命周期
    CameraX.bindToLifecycle(this, preview, imageAnalysis);
}

关键说明

  • 需提前申请相机权限(android.permission.CAMERA),并在运行时请求用户授权。
  • 相机帧尺寸与预览显示尺寸可能存在差异,需根据预览组件的缩放比例调整目标像素坐标。

内容的提问来源于stack exchange,提问作者Peter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 08:42:22