① android 图像处理 用什么库
没有,只有GPU
② Android如何进行图片编辑
裁剪选取或拍摄的图片
public static void cropphoto(Fragment fragment, Uri uri){ //设置裁剪图片保存位置 File bomb=new File(fragment.getContext().getExternalCacheDir(),"bmob"); Log.d("tag", "cropphoto: "+bomb); if (!bomb.exists()){ bomb.mkdir(); } File file=new File(bomb,"user_icon.jpg"); if (!file.exists()){ try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } Intent intent=new Intent("com.android.camera.action.CROP");//intent隐式调用启动拍照界面 intent.setDataAndType(uri,"image/*");//设置需要裁剪的图片地址 intent.putExtra("crop", "true");//通过put(key,value)方法设置相关属相 intent.putExtra("aspectX", 1);//设置图片宽高比例 intent.putExtra("aspectY", 1); intent.putExtra("outputX", 240);//设置图片宽高 intent.putExtra("outputY", 240); intent.putExtra("return-data", false);//该属性设置为false表示拍照后不会将数据返回到onResluet方法中(建议设置为false,这样获取的图片会比较清晰) intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));//该属性设置的是拍照后图片保存的位置 intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());//设置输出格式 intent.putExtra("noFaceDetection", true);//是否取消人脸识别 /*ComponentName componentName = intent.resolveActivity(context.getPackageManager()); Log.d("TAG", "cropphoto: "+componentName); if (componentName!=null){ fragment.startActivityForResult(intent,Variable.request_crop); }*/ fragment.startActivityForResult(intent,Variable.request_crop); }
③ android设置图片
1、创建imageview对象
2、设置imageview的图片
3、添加到布局中
示例代码
ViewGroup group = (ViewGroup) findViewById(R.id.viewGroup); //获取原来的布局容器
ImageView imageView = new ImageView(this); //创建imageview
imageView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT)); //image的布局方式
imageView.setImageResource(R.drawable.ic_launcher); //设置imageview呈现的图片
group.addView(imageView); //添加到布局容器中,显示图片。
④ Android 保存图片到本地。
这里只介绍按下“保存”后如何将一个Bitmap对象保存为图片文件的执行步骤,对图片的下载,图片到Bitmap对象的转换,Bitmap对象的格式转换和压缩,以及界面设计部分全部都忽略了。
确定存储路径
获取外部存储权限
确定外部存储状态
确定文件名
保存到文件中
发送广播,通知系统扫描保存后的文件
确定存储路径
在Android中文件存储路径包括内部存储和外部存储两种类型。
对内部存储,当一个app被安装到手机后,Android系统会在内部存储的/data/data/目录下创建一个以包名称命名的文件夹。例如/data/data/com.sohu.inputmethod.sogou/。一个应用对内部存储的所有访问都被限制在这个文件夹中,也就是说Android应用只能在该目录中读取,创建,修改文件。对该目录之外的其他内部存储中的目录都没有任何操作的权限。因此,如果将图片保存在内部存储中,只能被应用自身读取,其他应用均无法读取。如果需要让系统图库,相册或其他应用能够找到保存的图片,必须将图片保存到外部存储中。
对外部存储,当一个app被安装到手机后,Android系统会在外部存储的/Android/data/目录下创建一个以包名命名的文件夹(这里第一个/不是根路径,而是相对外部存储所挂载路径的相对路径)。例如/storage/emulated/0/Android/data/com.sohu.inputmethod/。这个路径同样只能被应用自身读取,其他应用不能访问。因此,也不能将图片保存在这个目录中。
除外部存储的/Android目录之外的其他目录一般都是可以被其他应用访问的。目前,大多数应用都会在外部存储的根路径下建立一个类似包名的多层目录,以存储需要共享的文件。例如/storage/emulated/0/sogou/image/。还需要注意的是,很多查看图片的应用都支持按照文件夹来查看图片。如果将图片所在的文件夹取名为image,photo之类的,就无法和其他文件夹区分开,用户也不能识别该文件夹的用途。因此最好取一个有区分度的文件夹名字,例如网络贴吧就保存在/tieba目录,微信是保存在/tencent/MicroMsg/WeiXin目录。
由于Android系统的碎片化问题,不同设备上外部存储的路径很可能会不同,因此,不能直接使用/storage/emulated/0/作为外部存储的根路径。
Android SDK中 Environment类 提供了getExternalStorageDirectory()方法来获取外部存储的根路径。示例如下:
[java]view plain
Stringdir=Environment.getExternalStorageDirectory().getAbsolutePath()+"/tencent/MicroMsg/WeiXin/"
需要注意的是Environment.getExternalStorageDirectory()返回的路径中最后一个字符不是/,如果需要创建子目录,需要在子目录的前后都加上/。
获取外部存储权限
由于需要在外部存储中写文件,需要在AndroidManifest.xml中增加如下的权限声明。
[java]view plain
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
确定外部存储状态
由于外部存储需要被挂载,也可以被卸载,在写入文件之前,需要先判断外部存储的状态是否正常。只有状态正常情况下才可以执行保存文件的操作。获取外部存储状态同样是通过Environment类,通过Environment.getExternalStorageState()可以得到一个字符串,来表示外部存储的状态。同时在Environment类中定义了一系列的String常量表示不同的状态。在所有的状态中只有内部存储处于Environment.MEDIA_MOUNTED状态时才可以读写文件,因此,需要将获取到的状态和Environment.MEDIA_MOUNTED做比较,如果不是Environment.MEDIA_MOUNTED状态,就返回保存失败。示例如下。
[java]view plain
//获取内部存储状态
Stringstate=Environment.getExternalStorageState();
//如果状态不是mounted,无法读写
if(!state.equals(Environment.MEDIA_MOUNTED)){
return;
}
确定文件名
保存的图片文件名可以由应用根据自身需要自行确定,一般来说需要有一个命名规则,然后根据命名规则计算得到文件名。
这里列举几种常见的命名规则。
随机命名
这种命名规则是随机生成一个字符串或一组数字来对图片命名。
字符串可以通过UUID来生成,数字可以通过Random()类来生成,例如:
[java]view plain
//通过UUID生成字符串文件名
StringfileName1=UUID.randomUUID().toString();
//通过Random()类生成数组命名
Randomrandom=newRandom();
StringfileName2=String.valueOf(random.nextInt(Integer.MAX_VALUE));
这种命名规则是按照数字从小到大的顺序来对图片命名。
在程序启动时先获取图片文件名中当前最大数字的文件名,之后每保存一张图片就将数字加1即可。
时间命名
这种命名规则是根据保存图片的当前系统时间来对图片命名。
系统时间可以通过System.currentTimeMillis()来获取,不过System.currentTimeMillis()获取到的时间是一个long型的整数,如果用它做文件名,无法通过文件名直接看出文件的具体保存时间。可以通过SimpleDateFormat先对当前时间做格式化,然后再将其作为文件名来使用。例如:
[java]view plain
使用这种命名规则来命名需要注意的是同一秒钟可能会有多张图片需要保存,在得到当前系统时间对应的文件名后,需要判断该文件是否存在。如果文件已经存在,需要重新生成文件名。重新生成的文件名可以在之前的文件名后加上一个随机数后缀,或者是用毫秒数做后缀。
Calendarnow=newGregorianCalendar();
SimpleDateFormatsimpleDate=newSimpleDateFormat("yyyyMMddHHmmss",Locale.getDefault());
StringfileName=simpleDate.format(now.getTime());
文件URL命名
每张网络图片都有一个对应的图片URL,可以根据图片的URL来对图片命名。
不过URL中会包含一些不能用作文件名的特殊字符,此外直接用URL来命名可能会带来安全问题。为了避免这两个问题,可以将图片URL的MD5值作为文件名来使用。由于MD5是不可逆的,也就无法通过MD5值反向得到图片URL,同时MD5值对应的字符串只包含[0-9A-Z],不包含特殊字符,可是作为文件名使用。
由于每张图片的URL是唯一的,其对应的文件名也就是唯一的。如果需要每张网络图片只能生成一个文件,不允许保存为多份拷贝,可以用这种命名规则。在得到URL对应的文件名后,先判断文件是否已经存在,如果已经存在,直接覆盖或不处理。
保存到文件中
保存图片文件时,通过Bitmap的compress()方法将Bitmap对象压缩到一个文件输出流中,然后flush()即可。示例如下。
[java]view plain
try{
Filefile=newFile(dir+fileName+".jpg");
FileOutputStreamout=newFileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.JPEG,100,out);
out.flush();
out.close();
}catch(Exceptione){
e.printStackTrace();
}
发送广播,通知系统扫描保存后的文件
至此,已经实现将Bitmap对象保存成外部存储中的一个jpg格式的文件。但此时该文件只是保存在外部存储的一个目录中,必须进入其所在的目录中才可以看到。在系统图库,相册和其他应用中无法看到新建的图片文件。为了让其他应用能够知道图片文件被创建,必须通知MediaProvider服务将新建的文件添加到图片数据库中。
Android系统中常驻一个MediaProvider服务,对应的进程名为android.process.media,此服务用来管理本机上的媒体文件,提供媒体管理服务。在系统开机或者收到外部存储的挂载消息后,MediaProvider会调用MediaScanner,MediaScanner会扫描外部存储中的所有文件,根据文件类型的后缀将文件信息保存到对应的数据库中,供其他APP使用。
MediaScannerReceiver是一个广播接收者,当它接收到特定的广播请求后,就会去扫描指定的文件,并根据文件信息将其添加到数据库中。当图片文件被创建后,就可以发送广播给MediaScannerReceiver,通知其扫描新建的图片文件。示例如下。
[java]view plain
try{
Filefile=newFile(dir+fileName+".jpg");
FileOutputStreamout=newFileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.JPEG,100,out);
out.flush();
out.close();
//保存图片后发送广播通知更新数据库
Uriuri=Uri.fromFile(file);
sendBroadcast(newIntent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,uri));
}catch(Exceptione){
e.printStackTrace();
}
图片的异步保存
保存图片文件时,如果图片很大,或需要同时保存多张图片时,就需要较多的时间。为了避免阻塞UI线程,出现帧率下降或ANR,通常需要将图片保存操作放到线程中去执行。当图片保存完毕后通过sendMessage()方法通知UI线程保存结果。
将图片保存放到后台线程去执行需要增加一些同步机制避免一些多线程问题。例如有两张图片需要保存,分别放到两个线程中去执行,保存图片时文件名以数字顺序增加。第一个线程选中文件名为125.jpg,但此时文件还未创建,第二个线程判断125.jpg不存在,于是也选取125.jpg作为文件名,两张图片就保存到同一个文件中了。
⑤ android中 怎么显示一直图片为圆形图片
android中的imageview只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆形的图片,这个时候,我们就需要自定义imageview了,其原理就是首先获取到图片的bitmap,然后进行裁剪圆形的bitmap,然后在ondraw()进行绘制圆形图片输出。
⑥ 求助,关于android图像识别。
你有图像识别库吗?如果有的话,App具体操作其实很简单,启动Camera采图嗲用库识别。
但是如果你没有图像识别库的话,你要自己去实现,一般库都是C++写的,我们公司用图像识别技术都是有专门的人写一个对应的图像识别库,而且对应扫描不同的东西都要单写一个库,然后打包给我们App调用,当然具体怎么写一个识别库,肯定也不是那么简单,必须要对C++如何实现图像识别技术要有一定基础的。
你要是有时间和精力想自己弄的话,推荐一个国外网站http://opencv.org/platforms/android.html,希望对你有帮助,都是这么苦逼过来的。
⑦ android怎么实现 图像随着手指的移动而移动
总得一句话要重写onTouchEvent 1.手势滚动有很多方法: 可用viewpager实现view的左右滑屏,也可以用ViewFlipper,还有笨方法就是一个imageview,获取按下抬起坐标,判断左滑右滑,然后set另一张图片进去。 2.缩放也有很多做法 正统的做法是把imageview的属性scaleType设置为matrix(矩阵),然后获取滑动手势,来操作矩阵获得缩放的效果
⑧ android如何实现图片预览
main.xml
先定义一个GridView,然后再定义一个ImageSwitcher
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<GridView
android:id="@+id/gridView1"
android:layout_height="fill_parent"
android:layout_width="300px"
android:layout_marginTop="6px"
android:horizontalSpacing="3px"
android:verticalSpacing="3px"
android:numColumns="4"/>
<ImageSwitcher
android:id="@+id/imageSwicher1"
android:padding="20px"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
></ImageSwitcher>
</LinearLayout>
MainActivity代码如下
{
privateint[]imageId=newint[]{R.drawable.w1,R.drawable.w2,
R.drawable.w3,R.drawable.w4,R.drawable.w5,R.drawable.w6};
;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
//TODOAuto-generatedmethodstub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageSwitcher=(ImageSwitcher)findViewById(R.id.imageSwicher1);
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_in));//设置淡入动画
imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_out));//设置谈出动画
imageSwitcher.setFactory(newViewFactory(){
@Override
publicViewmakeView(){
//TODOAuto-generatedmethodstub
ImageViewimageView=newImageView(MainActivity.this);//实例化一个ImageView类的对象
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);//设置保持纵横比居中缩放图像
imageView.setLayoutParams(newImageSwitcher.LayoutParams(//主要要是用ImageSwitcher的LayoutParams
LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
returnimageView;
}
});
imageSwitcher.setImageResource(imageId[0]);
GridViewgridView=(GridView)findViewById(R.id.gridView1);
BaseAdapteradapter=newBaseAdapter(){
/*
*获得数量
*
*@seeandroid.widget.Adapter#getCount()
*/
@Override
publicintgetCount(){
//TODOAuto-generatedmethodstub
returnimageId.length;
}
@Override
publicObjectgetItem(intposition){
//TODOAuto-generatedmethodstub
returnposition;
}
/**
*获得当前选项
*/
@Override
publiclonggetItemId(intposition){
//TODOAuto-generatedmethodstub
returnposition;
}
@Override
publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
//TODOAuto-generatedmethodstub
ImageViewimageView;
if(convertView==null){
imageView=newImageView(MainActivity.this);
/**设置图像的宽度和高度**/
imageView.setAdjustViewBounds(true);
imageView.setMaxWidth(150);
imageView.setMaxHeight(113);
imageView.setPadding(5,5,5,5);
}else{
imageView=(ImageView)convertView;
}
imageView.setImageResource(imageId[position]);
returnimageView;
}
};
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(newOnItemClickListener(){
@Override
publicvoidonItemClick(AdapterView<?>arg0,Viewarg1,intarg2,
longarg3){
//TODOAuto-generatedmethodstub
imageSwitcher.setImageResource(imageId[arg2]);//显示选中的图片
}
});
}
}
⑨ Android绘制图片的几种方式
在android中做图像镜像有很多方法,今天算是学习了!
两种方法如下:
复制代码 代码如下:
//方法一
Matrix matrix = new Matrix();
matrix.postScale(leftOrRight, 1, bmpW/2, bmpH/2);//前两个是xy变换,后两个是对称轴中心点
matrix.postTranslate(x, y);
canvas.drawBitmap(bmpLuffy[0], matrix, paint);
//方法二
// canvas.save();
// canvas.scale(-1, 1, x + bmpLuffy[0].getWidth() / 2, y + bmpLuffy[0].getHeight() / 2);
// canvas.drawBitmap(bmpLuffy[0], x, y, paint);
// canvas.restore();
方法一,使用矩阵的方式(3x3)矩阵:
1、先使用postScale的方式将图片以点(bmpW/2,bmpH/2)为中心,以x=bmpW/2为对称轴翻转;
2、使用postTranslate,将图片移到(x,y)坐标
方法二,画布翻转(略)
注意如下问题:
对于其中的bmpW和bmpH是指所用图片的宽高,需要使用图片bmp.getWidth()和bmp.getHeight()获取,
不能使用PC上看到的大小,否则可能会出现错位!