android获取图片宽高
⑴ android 图片质量压缩和尺寸压缩有什么区别
这个方法用来将特定格式的压缩图片写入输出流(OutputStream)中,当然例如输出流与文件联系在一起,压缩后的图片也就是一个文件。如果压缩成功则返回true,其中有三个参数:
format是压缩后的图片的格式,可取值:Bitmap.CompressFormat .JPEG、~.PNG、~.WEBP。
quality的取值范围为[0,100],值越小,经过压缩后图片失真越严重,当然图片文件也会越小。(PNG格式的图片会忽略这个值的设定)
stream指定压缩的图片输出的地方,比如某文件。
上述方法还有一个值得注意的地方是:当用BitmapFactory decode文件时可能返回一个跟原图片不同位深的图片,或者丢失了每个像素的透明值(alpha),比如说,JPEG格式的图片仅仅支持不透明的像素。文章android图片压缩在文末提到的下面这点可能就是这个原因:
当调用bitmap.compress(CompressFormat.JPEG, 100, fos);保存为图片时发现图片背景为黑色,如下图:
下面是质量压缩的代码:
(Bitmapbmp,Filefile){
ByteArrayOutputStreambaos=newByteArrayOutputStream();
intoptions=80;//个人喜欢从80开始,
bmp.compress(Bitmap.CompressFormat.JPEG,options,baos);
while(baos.toByteArray().length/1024>100){
baos.reset();
options-=10;
bmp.compress(Bitmap.CompressFormat.JPEG,options,baos);
}
try{
FileOutputStreamfos=newFileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
}catch(Exceptione){
e.printStackTrace();
}
}
这段代码来自Android图片压缩总结,我根据自己的需求改了改,但是大同小异,所以就直接贴了。
随着代码中的option逐渐变小,我们可以在logcat中打印baos的大小来查看图片的大小。我们也可以去掉while的循环条件,一直压缩下去看效果,最终一张照片可能就由原来的3、4M变成了几百K甚至几百B了。我在试的过程中将option设置成100,压缩后偶尔会出现一张3、4M的图片经过压缩后竟变成了6、7M,这里还是有点困惑,不知道为什么。
随后,我想把这个压缩后的图片(1、200KB)填充到ImageView中时却失败了,logcat中提示图片过大!这就是文章开头提到的问题,虽然我们通过质量压缩使File形式的图片文件缩小了,但是并没有改变图片的宽高,原先是1080*1920分辨率的图片经压缩后还是1080*1920,而File格式转换成Bitmap格式进入到内存中时,内存是根据图片的像素数量来给图片分配内存大小的,还是有好几M,因此填充ImageView失败。
顺便提一下,可以用bitmap.getByteCount()获取存储bitmap像素的内存大小,但是KITKAT(Android 4.4版本)以后用getAllocateByteCount()获取。一般情况下,后者返回值比前者大,比如,当bitmap被重用去decode另外更小的bitmaps时,或者被人为地配置一下属性值,比如setWidth()、setHeight()、reconfigure()时,如果bitmap不做以上操作,二者的返回值应该是一样的。(译文,不太懂)
二、尺寸压缩
特点: 通过设置采样率, 减少图片的像素, 达到对内存中的Bitmap进行压缩
我们主要通过BitmapFactory中的decodeFile方法对图片进行尺寸压缩:
publicstaticBitmapdecodeFile(StringpathName,BitmapFactory.Optionsopts)
public static Bitmap decodeFile (String pathName, BitmapFactory.Options opts)
其中有两个参数:
pathName是图片文件的路径。
opts 就是所谓的采样率,它里边有很多属性可以设置,我们通过设置属性来达到根据自己的需要,压缩出指定的图片。其中比较常用的属性有:
booleaninJustDecodeBounds—— 如果设置为true,则只读取bitmap的宽高,而忽略内容。
intinSampleSize—— 如果>1,调用decodeFile方法后,就会得到一个更小的bitmap对象(已压缩)。比如设置为2,那么新Bitmap的宽高都会是原Bitmap宽高的1/2,总体大小自然就是原来的1/4了,以此类推。
booleaninPurgeable—— 如果设置为true,压缩后的图片像素占的内存将会在系统清理内存的时候被回收掉,当像素的信息再次被用到时将会自动重新decode该像素(比如getPixels()时)。(慎用!重复decode可以会造成UI的卡顿,API level 21 已弃用)
booleaninInputShareable—— 与inPurgeable配合使用,如果inPurgeable设置成false,自动忽略此值,如果inPurgeable为true,此值决定是否该bitmap能分享引用给输入数据(inputstream,array等),或者必须进行深拷贝。API level 21 已弃用。(这是译文,不太理解!!!)
下面是一段实现的代码
privateBitmapsizeCompres(Stringpath,intrqsW,intrqsH){
//用option设置返回的bitmap对象的一些属性参数
finalBitmapFactory.Optionsoptions=newBitmapFactory.Options();
options.inJustDecodeBounds=true;//设置仅读取Bitmap的宽高而不读取内容
BitmapFactory.decodeFile(path,options);//获取到图片的宽高,放在option里边
finalintheight=options.outHeight;//图片的高度放在option里的outHeight属性中
finalintwidth=options.outWidth;
intinSampleSize=1;
if(rqsW==0||rqsH==0){
options.inSampleSize=1;
}elseif(height>rqsH||width>rqsW){
finalintheightRatio=Math.round((float)height/(float)rqsH);
finalintwidthRatio=Math.round((float)width/(float)rqsW);
inSampleSize=heightRatio<widthRatio?heightRatio:widthRatio;
options.inSampleSize=inSampleSize;
}
returnBitmapFactory.decodeFile(path,options);//主要通过option里的inSampleSize对原图片进行按比例压缩
}
private Bitmap sizeCompres(String path, int rqsW, int rqsH) {
// 用option设置返回的bitmap对象的一些属性参数
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;// 设置仅读取Bitmap的宽高而不读取内容
BitmapFactory.decodeFile(path, options);// 获取到图片的宽高,放在option里边
final int height = options.outHeight;//图片的高度放在option里的outHeight属性中
final int width = options.outWidth;
int inSampleSize = 1;
if (rqsW == 0 || rqsH == 0) {
options.inSampleSize = 1;
} else if (height > rqsH || width > rqsW) {
final int heightRatio = Math.round((float) height / (float) rqsH);
final int widthRatio = Math.round((float) width / (float) rqsW);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
options.inSampleSize = inSampleSize;
}
return BitmapFactory.decodeFile(path, options);// 主要通过option里的inSampleSize对原图片进行按比例压缩
}
上面就是简单的质量压缩与尺寸压缩。
⑵ android怎么获取图片的大小
1、控制大小和位置
/*
* 获取对话框的窗口对象及参数对象以修改对话框的布局设置,
* 可以直接调用getWindow(),表示获得这个Activity的Window
* 对象,这样这可以以同样的方式改变这个Activity的属性.
*/
Window dialogWindow = dialog.getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.LEFT | Gravity.TOP);
/*
* lp.x与lp.y表示相对于原始位置的偏移.
* 当参数值包含Gravity.LEFT时,对话框出现在左边,所以lp.x就表示相对左边的偏移,负值忽略.
* 当参数值包含Gravity.RIGHT时,对话框出现在右边,所以lp.x就表示相对右边的偏移,负值忽略.
* 当参数值包含Gravity.TOP时,对话框出现在上边,所以lp.y就表示相对上边的偏移,负值忽略.
* 当参数值包含Gravity.BOTTOM时,对话框出现在下边,所以lp.y就表示相对下边的偏移,负值忽略.
* 当参数值包含Gravity.CENTER_HORIZONTAL时
* ,对话框水平居中,所以lp.x就表示在水平居中的位置移动lp.x像素,正值向右移动,负值向左移动.
* 当参数值包含Gravity.CENTER_VERTICAL时
* ,对话框垂直居中,所以lp.y就表示在垂直居中的位置移动lp.y像素,正值向右移动,负值向左移动.
* gravity的默认值为Gravity.CENTER,即Gravity.CENTER_HORIZONTAL |
* Gravity.CENTER_VERTICAL.
*
* 本来setGravity的参数值为Gravity.LEFT | Gravity.TOP时对话框应出现在程序的左上角,但在
* 我手机上测试时发现距左边与上边都有一小段距离,而且垂直坐标把程序标题栏也计算在内了,
* Gravity.LEFT, Gravity.TOP, Gravity.BOTTOM与Gravity.RIGHT都是如此,据边界有一小段距离
*/
lp.x = 100; // 新位置X坐标
lp.y = 100; // 新位置Y坐标
lp.width = 300; // 宽度
lp.height = 300; // 高度
lp.alpha = 0.7f; // 透明度
// 当Window的Attributes改变时系统会调用此函数,可以直接调用以应用上面对窗口参数的更改,也可以用setAttributes
// dialog.onWindowAttributesChanged(lp);
dialogWindow.setAttributes(lp);
/*
* 将对话框的大小按屏幕大小的百分比设置
*/
// WindowManager m = getWindowManager();
// Display d = m.getDefaultDisplay(); // 获取屏幕宽、高用
// WindowManager.LayoutParams p = getWindow().getAttributes(); // 获取对话框当前的参数值
// p.height = (int) (d.getHeight() * 0.6); // 高度设置为屏幕的0.6
// p.width = (int) (d.getWidth() * 0.65); // 宽度设置为屏幕的0.95
// dialogWindow.setAttributes(p);
⑶ android 从服务器端获取图片,有的图片太大了,要压缩,但我不知道要压缩到什么样的尺寸合适。
根据你的imageiew大小来定,同时要注意长宽比
如果原图的长宽比大于你的imageiew的长宽比,按长度的比例来缩放
反之按宽度来
如果正好相等,那么哪一个都可以了。
⑷ android怎么获取drawble图片高宽
先找到这个控件,把drawble转换成bitmap,然后获取bitmap的宽高即可。主要代码如下:
Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.id.XXX);
int height = bitmap.getHeight();
int width= bitmap.getWidth();
最后,祝你早日解决问题。
⑸ android 怎样获取图像触摸位置的rgb值
基本介绍
思路:
一
首先需要一张图片,这里由于我的强迫症,我没有写死,而是去图库选择一张照片。
二
获取图片的宽、高,为了精度,这里一定要设置BitmapFactory.Options,通过坐标的形式来获取RGB值,也就是说把一张图片通过坐标分为若干个小点。
上代码:
privateBitmapcomp(Bitmapimage){
ByteArrayOutputStreambaos=newByteArrayOutputStream();
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中
}
ByteArrayInputStreamisBm=newByteArrayInputStream(baos.toByteArray());
BitmapFactory.OptionsnewOpts=newBitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds设回true了
newOpts.inJustDecodeBounds=true;
Bitmapbitmap=BitmapFactory.decodeStream(isBm,null,newOpts);
newOpts.inJustDecodeBounds=false;
intw=newOpts.outWidth;
inth=newOpts.outHeight;
//现在主流手机比较多是800*500分辨率,所以高和宽我们设置为
floathh=800f;//这里设置高度为800f
floatww=500f;//这里设置宽度为500f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
intbe=1;//be=1表示不缩放
if(w>h&&w>ww){//如果宽度大的话根据宽度固定大小缩放
be=(int)(newOpts.outWidth/ww);
}elseif(w<h&&h>hh){//如果高度高的话根据宽度固定大小缩放
be=(int)(newOpts.outHeight/hh);
}
if(be<=0)
be=1;
newOpts.inSampleSize=be;//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds设回false了
isBm=newByteArrayInputStream(baos.toByteArray());
bitmap=BitmapFactory.decodeStream(isBm,null,newOpts);
returncompressImage(bitmap);//压缩好比例大小后再进行质量压缩
}
重点:一定要设置BitmapFactory.Options newOpts = new BitmapFactory.Options();否则坐标获取不准确
三
通过getPixel(x, y)方法通过坐标拿到我们需要的色值即可,比较简单。
iv_image.setOnTouchListener(newOnTouchListener(){
@Override
publicbooleanonTouch(Viewv,MotionEventevent){
intx=(int)event.getX();
inty=(int)event.getY();
if(event.getAction()==MotionEvent.ACTION_UP){
intcolor=bitmap.getPixel(x,y);
//如果你想做的更细致的话可以把颜色值的RGB拿到做响应的处理
intr=Color.red(color);
intg=Color.green(color);
intb=Color.blue(color);
inta=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));
}
returntrue;
}
});
⑹ android 获取的图片尺寸比图片属性显示的尺寸大很多
起因是测试在测试过程中发现需要裁剪的图片看不到,但是还能继续裁剪。
所以就检查代码,发现了bitmap的width和Height有3000多。
然后试了下把图片改成300*300的就显示正常,
所以我们需要让图片根据大小不同,机器不同而改变图片的宽高
//设置分辨率
//1.获取系统分辨率
Resources resources = this.getResources();
DisplayMetrics dm = resources.getDisplayMetrics();
//2.获取图片分辨率
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;// 这个方式不会在内存创建一张图片,
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options); //此时返回的bitmap为null,但是option会保留一部分参数
//3.确定分辨率
int height = options.outHeight;
int width = options.outWidth;
if(options.outHeight>dm.heightPixels*1.5f){//当图片大小比屏幕大1.5倍的时候,直接以系统高度为高度
height = dm.heightPixels;
}
if (options.outWidth>dm.widthPixels*1.5f){
width = dm.widthPixels;
}
options.inJustDecodeBounds = false;
⑺ android 下怎样获取图片像素值
int[] pixels = new int[bit.getWidth()*bit.getHeight()];//保存所有的像素的数组,图片宽×高
bit.getPixels(pixels,0,bit.getWidth(),0,0,bit.getWidth(),bit.getHeight());
for(int i = 0; i < pixels.length; i++){
int clr = pixels[i];
int red = (clr & 0x00ff0000) >> 16; //取高两位
int green = (clr & 0x0000ff00) >> 8; //取中两位
int blue = clr & 0x000000ff; //取低两位
System.out.println("r="+red+",g="+green+",b="+blue);
}
其中getPixels中第三个参数要为图片的宽度