Android获取图片任意一点的RGB值
2015-12-01 14:43
316 查看
最近要做一个点击图片任何一个地方取色值然后传给蓝牙设备的一个功能。在网上搜索了一番,大部分都是重复,有的功能实现了,但是效果不好,大部分都取色值不准确,偏差有点大,于是决定还是自己动手写了一个,在这里分享给大家,有需要的朋友可以下载我写的这个小demo。
![](http://img.blog.csdn.net/20151201144300960)
上代码:
重点:一定要设置BitmapFactory.Options newOpts = new BitmapFactory.Options();否则坐标获取不准确
github:https://github.com/Jackwaiting/RGB-to-get-the-Android-value-of-the-picture
有问题或好的建议可以给我留言。
效果:
基本介绍
思路:
一
首先需要一张图片,这里由于我的强迫症,我没有写死,而是去图库选择一张照片。二
获取图片的宽、高,为了精度,这里一定要设置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/9315769github:https://github.com/Jackwaiting/RGB-to-get-the-Android-value-of-the-picture
有问题或好的建议可以给我留言。
相关文章推荐
- Android 使用SharedPreferences 进行保存账号or密码or其它数据
- Android 料阅读及视频观看,先下载后打开
- mac 安卓调试 找不到手机
- Android代码混淆之混淆规则
- 29个android开发常用的类、方法及接口
- Android Frame动画
- Android Studio 快捷键
- android 自定义跑马灯
- Android编程实现屏幕自适应方向尺寸与分辨率的方法
- Android MotionEvent中getX()和getRawX()的区别
- Android开发 深入理解AsyncTask
- android studio对.9格式图片的支持
- 调用手机相机拍照并获取拍摄的照片
- 八款Android 开发者必备的小工具
- getMeasuredHeight()与getHeight的区别
- android Material主题中的button效果
- Android从入门到精通标配四阶段
- android.intent.action.MAIN和singleTask模式一起使用导致每次进入应用都会进入该Activity
- Android与IOS的Transform图形变换矩阵之间快速转换方法
- android之往手机内存合sdcard卡上存储数据