Android获取图片任意一点的RGB值

标签: android 图片 rgb 蓝牙 搜索
17121人阅读 评论(8) 收藏 举报
分类:

最近要做一个点击图片任何一个地方取色值然后传给蓝牙设备的一个功能。在网上搜索了一番,大部分都是重复,有的功能实现了,但是效果不好,大部分都取色值不准确,偏差有点大,于是决定还是自己动手写了一个,在这里分享给大家,有需要的朋友可以下载我写的这个小demo。

效果:

这里写图片描述

基本介绍

思路:

首先需要一张图片,这里由于我的强迫症,我没有写死,而是去图库选择一张照片。

获取图片的宽、高,为了精度,这里一定要设置BitmapFactory.Options,通过坐标的形式来获取RGB值,也就是说把一张图片通过坐标分为若干个小点。
上代码:

    private Bitmap comp(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        if (baos.toByteArray().length / 1024 > 1024) {
            //判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
            baos.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 50, baos);
            //这里压缩50%,把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        //现在主流手机比较多是800*500分辨率,所以高和宽我们设置为
        float hh = 800f;//这里设置高度为800f
        float ww = 500f;//这里设置宽度为500f
        //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;//设置缩放比例
        //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
    }

重点:一定要设置BitmapFactory.Options newOpts = new BitmapFactory.Options();否则坐标获取不准确

通过getPixel(x, y)方法通过坐标拿到我们需要的色值即可,比较简单。

iv_image.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int x = (int) event.getX();

                int y = (int) event.getY();

                if (event.getAction() == MotionEvent.ACTION_UP) {
                    int color = bitmap.getPixel(x, y);
                    // 如果你想做的更细致的话 可以把颜色值的R G B 拿到做响应的处理
                    int r = Color.red(color);
                    int g = Color.green(color);
                    int b = Color.blue(color);
                    int a = Color.alpha(color);
                    Log.i(TAG, "r=" + r + ",g=" + g + ",b=" + b);
                    tv_rgb.setText("a=" + a + ",r=" + r + ",g=" + g + ",b="
                            + b);
                    btnColor.setTextColor(Color.rgb(r, g, b));
                }
                return true;
            }
        });

四、完整代码、

RGBActivity

package com.rgb;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class RGBActivity extends Activity {
    private TextView tv_rgb;
    private ImageView iv_image;
    private Bitmap bitmap;
    private String TAG = "RGBActivity";
    private Button btnColor;
    public static final int NONE = 0;
    public static final int PHOTOHRAPH = 1;// 拍照
    public static final int PHOTOZOOM = 2; // 缩放
    public static final int PHOTORESOULT = 3;// 结果
    public static final String IMAGE_UNSPECIFIED = "image/*";
    public static final String TEMP_JPG_NAME = "temp.jpg";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rgb);


        tv_rgb = (TextView) findViewById(R.id.textview);
        btnColor = (Button) findViewById(R.id.btnColor);
        iv_image = (ImageView) findViewById(R.id.iv_image);
        btnColor.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                 openAlbum();
            }
        });
        iv_image.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int x = (int) event.getX();

                int y = (int) event.getY();

                if (event.getAction() == MotionEvent.ACTION_UP) {
                    int color = bitmap.getPixel(x, y);
                    // 如果你想做的更细致的话 可以把颜色值的R G B 拿到做响应的处理
                    int r = Color.red(color);
                    int g = Color.green(color);
                    int b = Color.blue(color);
                    int a = Color.alpha(color);
                    Log.i(TAG, "r=" + r + ",g=" + g + ",b=" + b);
                    tv_rgb.setText("a=" + a + ",r=" + r + ",g=" + g + ",b="
                            + b);
                    btnColor.setTextColor(Color.rgb(r, g, b));
                }
                return true;
            }
        });
    }

     // 打开相册
    private void openAlbum() {
      /*  Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image*//*");*/

        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                "image/*");
     /*
       Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);*/
        startActivityForResult(intent, PHOTOZOOM);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        try {

            if (resultCode == NONE)
                return;

            if (data == null)
                return;

            // 读取相册缩放图片
            if (requestCode == PHOTOZOOM) {
              /*  Uri image = data.getData();
                Toast.makeText(MymessageActivity.this,image+"", Toast.LENGTH_LONG).show();*/

                if (data != null) {
                    startPhotoZoom(data.getData());
                }

            }

            // 处理结果
            if (requestCode == PHOTORESOULT) {
                Bundle extras = data.getExtras();
                if (extras != null) {
                    bitmap = extras.getParcelable("data");
                    //ByteArrayOutputStream stream = new ByteArrayOutputStream();
                    comp(bitmap);
                    //bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
                    iv_image.setImageBitmap(bitmap);
                   /* logoName = FileUtils.getFilename(MainAppUtil.getCustom().getSusername());
                    FileUtils.writeFile(Constants.LOGO_CACHE_PATH, logoName, photo);*/
                }
            }

            super.onActivityResult(requestCode, resultCode, data);
        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    private Bitmap compressImage(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
            options -= 10;//每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
        return bitmap;
    }

    private Bitmap comp(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        if (baos.toByteArray().length / 1024 > 1024) {
            //判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
            baos.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 50, baos);
            //这里压缩50%,把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        //现在主流手机比较多是800*500分辨率,所以高和宽我们设置为
        float hh = 800f;//这里设置高度为800f
        float ww = 500f;//这里设置宽度为500f
        //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;//设置缩放比例
        //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
    }

    private void startPhotoZoom(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, IMAGE_UNSPECIFIED);
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 300);
        intent.putExtra("outputY", 300);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, PHOTORESOULT);
    }
}

activity_rgb.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btnColor"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:text="获取图片" />

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20.0sp" />

    <ImageView
        android:id="@+id/iv_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:scaleType="fitCenter" />

</LinearLayout>

项目下载地址:

csdn:http://download.csdn.net/detail/zhanggang740/9315769
github:https://github.com/Jackwaiting/RGB-to-get-the-Android-value-of-the-picture

有问题或好的建议可以给我留言。

查看评论

android中获取 bitmap 像素的颜色 之吸管取色功能

本功能是参考android API colorPickerView修改,实现类似与PS中吸管取色功能。也就是可以对图片的任意位置取该位置的RGB。本demo中,完成了色盘取色功能。当点击色盘的某个位置...
  • killcwd
  • killcwd
  • 2014-11-07 19:24:11
  • 2366

android中 bitmap 获取像素的RGB

对图片的特定位置取色,比如类似与吸管效果。取色后如何获取其R、G、B、A 代码如下:         int color = bitmap.getPixel(x, y);//x、y为bi...
  • cc20032706
  • cc20032706
  • 2014-07-08 16:37:23
  • 4894

Android中Bitmap类getPixel方法获取的像素值为负

最近在做Android上的图像处理,在Android上直接对像素操作,居然出现了意想不到的事情。Bitmap类getPixel方法获取的像素值全部是负的,本来应该是黑色的,也就是0的,全部变成了-16...
  • ruanjianxiong
  • ruanjianxiong
  • 2011-08-25 13:47:40
  • 12231

android图片特效之取主色

有时候在布置界面的时候,配色的好坏直接关系到一个应用的美观和用户体验。如果能够自动产生一种配色使得背景与图片融为一体,那就再好不过了。而且目前,网上也有累似的功能的开源项目,可以顺手拈来。比如: h...
  • rj113
  • rj113
  • 2014-12-29 20:06:14
  • 2166

Android 读取图片的颜色值

Android SDK中提供了Bitmap图片每个像素颜色读取的方法: public void getPixColor(){ Bitmap src =  BitmapFactory.dec...
  • sdliubo
  • sdliubo
  • 2015-02-03 11:54:48
  • 12562

Android 把bitmap图片的某一部分的颜色改成其他颜色

private Bitmap ChangeBitmap(Bitmap bitmap){ int bitmap_h; int bitmap_w; int mArrayColor...
  • only_you_zj
  • only_you_zj
  • 2017-07-15 16:24:30
  • 989

【Android】二进制图片和Bitmap的getPixel方法解析

Android中Bitmap的getPixel方法解析 第一次写博客,一直想动笔,但是感觉想写的东西网上都有很详细的了。。。今天终于下定决心,写第一篇博客。感觉博客这个东西,别人的和自己的是不一样的...
  • w855227
  • w855227
  • 2018-02-24 18:02:54
  • 41

最快最简单的android屏幕取色(懒人办法)

使用QQ截图,截图的焦点所在的屏幕点会显示RGB的值 打开网页输入RGB颜色转换为html代码 懒的打开PS...
  • b275518834
  • b275518834
  • 2015-02-26 23:11:00
  • 7857

Android 最完美的取色盘ColorPickView

前言: 百度一番之后,有用张图片来代替取色盘,用Bitmap.getPixel()功能取色,的确可以。但瑕疵太大。比如,图片的RGB分布远不如HSV模型用代码写的取色盘那样细腻,无法反向定位(根据...
  • sinat_27033869
  • sinat_27033869
  • 2017-06-29 10:30:26
  • 3141

AndroidStudio取色器

开发过程中,经常会用到取色器。下面介绍AndroidStudio本身自带取色器使用过程。使用步骤 依次打开File、Settings、Keymap。如图: 如图,搜索Color Picker; 如图,...
  • zsp_android_com
  • zsp_android_com
  • 2017-08-08 17:03:06
  • 1919
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 26万+
    积分: 2690
    排名: 1万+
    博客专栏
    文章分类
    最新评论