android拍照选择图片上传服务器自定义控件
做android项目的时候总免不了遇到图片上传功能,虽然就是调用android系统的拍照和相册选择功能,但是总面部了把一大推代码写在activity里,看上去一大推代码头都昏了。不如把这些功能都集成一个控件,以后遇到图片上传功能也不用那么麻烦了。好啦,下面开始上效果图。
</pre><pre name="code" class="java" style="font-size: 11.8181819915771px;">
</pre><pre name="code" class="java" style="font-size: 11.8181819915771px;">
效果图就是这样了,我们看效果图可以分析出大致的功能就是:一个Imageview里默认有一张图片,我们在选择了图片以后右上角有个删除的Imageview,点击以后可以删除选择的图片,那实际上就是一个FrameLayout嘛,好,下面开始贴代码。基本看代码都能看懂了,需要注意的是做了一下图片压缩的处理。因为不做压缩的话一个图片拍下来都是几兆大小,上传完全不可行。
</pre><pre name="code" class="java" style="font-size: 11.8181819915771px;">自定义控件代码
</pre><pre name="code" class="java">
public class ImagePicker extends FrameLayout implements View.OnClickListener {
private SelectType selectType; //选择的类型照相和选择
private Context context;
private ImageView imageView;
private ImageView deleteImageView;
private int imageViewWidth;
private int imageViewHeight;
private boolean hasImage;
private String imagePath;
private File file;
private LinearLayout dialogView;
private AlertDialog dialog;
private int scaleWidth=240;
private int scaleHeight=240;
public void setScale(int width,int height){
this.scaleWidth=width;
this.scaleHeight=height;
}
public ImagePicker(Context context) {
super(context);
this.context=context;
}
public ImagePicker(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
}
public ImagePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context=context;
}
public boolean hasImage(){
return this.hasImage;
}
public String getImagePath(){
return this.imagePath;
}
public void setImagePath(String path){
File file=new File(path);
if(!file.exists()){
clearImagePicker();
return;
}
Bitmap bitmap=ImageUtils.getInstance().decodeSampledBitmap(file,imageViewWidth,imageViewHeight);
if(bitmap==null){
clearImagePicker();
return;
}
int degree = ImageUtils.getInstance().readPicDegree(path);
if(degree>0){
bitmap=ImageUtils.getInstance().rotateBitmap(degree,bitmap);
}
imageView.setImageBitmap(bitmap);
imagePath=path;
hasImage=true;
deleteImageView.setVisibility(View.VISIBLE);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK&&
requestCode == getId()) {
if(selectType==null){
selectType=SelectType.CAMERA;
}
switch (selectType){
case CAMERA:
onCameraResult(data);
break;
case PHOTO:
onPhotoResult(data);
break;
}
}
}
private void onPhotoResult(Intent data){
Uri originalUri = data.getData();
Cursor cursor = ((Activity)context).managedQuery(originalUri, new String[]{MediaStore.Images.Media.DATA}, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String path = cursor.getString(column_index);
try {
File tmpFile=compressImage(path);
setImagePath(tmpFile.getPath());
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context,"压缩图片失败",Toast.LENGTH_SHORT).show();
clearImagePicker();
return;
}
}
private void onCameraResult(Intent data){
try {
File tmpFile=compressImage(file.getPath());
setImagePath(tmpFile.getPath());
file.delete();
file=tmpFile;
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context,"压缩图片失败",Toast.LENGTH_SHORT).show();
clearImagePicker();
return;
}
}
private File compressImage(String path) throws IOException {
//图片翻转角度
int degree=ImageUtils.getInstance().readPicDegree(path);
//缩放
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path,newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
int be = 1;
if (w > h && w > scaleWidth) {
be = newOpts.outWidth / scaleWidth;
} else if (w < h && h > scaleHeight) {
be = newOpts.outHeight / scaleHeight;
}
if (be <= 0){
be = 1;
}
newOpts.inSampleSize = be;
Bitmap bitmap = BitmapFactory.decodeFile(path, newOpts);
if(degree>0){
bitmap=ImageUtils.getInstance().rotateBitmap(degree,bitmap);
}
//压缩
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 100;
while ( baos.toByteArray().length / 1024>100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
options -= 10;
baos.reset();
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
//保存
String name = new DateFormat().format("yyyyMMddhhmmss", Calendar.getInstance()) + ".jpg";
File file = new File(SDCardUtils.getImageDir(context),name);
FileOutputStream b = new FileOutputStream(file);
baos.writeTo(b);
baos.close();
b.close();
return file;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
imageView=(ImageView)this.findViewById(R.id.ImagePicker_ImageView);
deleteImageView=(ImageView)this.findViewById(R.id.ImagePicker_ImageDelete);
imageView.setOnClickListener(this);
deleteImageView.setOnClickListener(this);
deleteImageView.setVisibility(View.GONE);
dialogView=(LinearLayout)LayoutInflater.from(this.context).inflate(R.layout.image_picker_dialog_layout,null);
dialogView.findViewById(R.id.ImagePicker_PhotoBtn).setOnClickListener(this);
dialogView.findViewById(R.id.ImagePicker_CameraBtn).setOnClickListener(this);
dialogView.findViewById(R.id.ImagePicker_CancelBtn).setOnClickListener(this);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
imageViewWidth=imageView.getWidth();;
imageViewHeight=imageView.getHeight();;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.ImagePicker_ImageView:
showImagePickerDialog();
break;
case R.id.ImagePicker_ImageDelete:
clearImagePicker();
break;
case R.id.ImagePicker_CameraBtn:
showCameraApp();
break;
case R.id.ImagePicker_PhotoBtn:
showPhotoApp();
break;
case R.id.ImagePicker_CancelBtn:
closeDialog();
break;
}
}
private void closeDialog(){
dialog.dismiss();
dialog=null;
}
private void showImagePickerDialog(){
ViewGroup parent=(ViewGroup)dialogView.getParent();
if(parent!=null){
parent.removeView(dialogView);
}
dialog= new AlertDialog.Builder(context).setTitle("图片选择")
.setView(dialogView).create();
dialog.show();
}
private void showPhotoApp(){
selectType=SelectType.PHOTO;
Intent photoIntent= new Intent(Intent.ACTION_GET_CONTENT);
photoIntent.setType("image/*");
((Activity)context).startActivityForResult(photoIntent, getId());
closeDialog();
}
private void showCameraApp(){
if(!SDCardUtils.hasSDCard()){
Toast.makeText(context,"请插入sd卡",Toast.LENGTH_SHORT).show();
return;
}
String name = new DateFormat().format("yyyyMMddhhmmss", Calendar.getInstance()) + ".jpg";
file = new File(SDCardUtils.getImageDir(context),name);
selectType=SelectType.CAMERA;
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
((Activity)context).startActivityForResult(cameraIntent, getId());
closeDialog();
}
public void clearImagePicker(){
hasImage=false;
imagePath=null;
imageView.setImageResource(R.drawable.image_picker_add);
deleteImageView.setVisibility(View.GONE);
}
enum SelectType{
PHOTO,CAMERA
}
}
</pre><p></p><p>我们的控件布局是这样的。</p><p></p><pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>
<com.example.imageUpload.widget.ImagePicker xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="10dip"
android:id="@+id/ImagePicker_ImageView"
android:layout_gravity="center"
android:src="@drawable/image_picker_add"
android:scaleType="fitXY"/>
<ImageView
android:layout_width="20dip"
android:layout_height="20dip"
android:id="@+id/ImagePicker_ImageDelete"
android:src="@drawable/image_picker_delete"
android:layout_gravity="right|top" />
</com.example.imageUpload.widget.ImagePicker>
下面开始使用吧!在activity的xml文件里面include一下就可以了,布局代码我就不贴了,来看activity里面。我们需要重写一下onActivityResult,
上传文件我们无非就是用到 //imagePicker1.getImagePath();得到图片的路径
//imagePicker1.hasImage();是否有图片。
public class MyActivity extends Activity {
private ImagePicker imagePicker1;
private ImagePicker imagePicker2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imagePicker1 = (ImagePicker)findViewById(R.id.imagePicker1);
imagePicker2 = (ImagePicker)findViewById(R.id.imagePicker2);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
imagePicker1.onActivityResult(requestCode, resultCode, data);
imagePicker2.onActivityResult(requestCode,resultCode,data);
//imagePicker1.getImagePath();
//imagePicker1.hasImage();
}
}
android拍照选择图片上传服务器自定义控件的更多相关文章
- Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等
仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...
- HTML5 Plus 拍照或者相册选择图片上传
HBuilder+HTML5 Plus+MUI实现拍照或者相册选择图片上传,利用HTML5 Plus的Camera.Gallery.IO.Storage和Uploader来实现手机APP拍照或者从相册 ...
- H5拍照、选择图片上传组件核心
背景 前段时间项目重构,改成SSR的项目,但之前用的图片选择上传组件不支持SSR(server-side-render).遂进行了调研,发现很多的工具.但有的太大,有的使用麻烦,有的不满足使用需求.决 ...
- [转]微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
本文转自:http://blog.csdn.net/qq_31383345/article/details/53014610 今天遇到微信小程序的用户头像设置功能,做笔记. 先上gif: 再上代码: ...
- 微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
1.index.wxml <!--index.wxml--> <button style="margin:30rpx;" bindtap="choose ...
- MVC4中基于bootstrap和HTML5的图片上传Jquery自定义控件
场景:mvc4中上传图片,批量上传,上传前浏览,操作.图片进度条. 解决:自定义jquery控件 没有解决:非图片上传时,会有浏览样式的问题; 解决方案; 1.样式 – bootstrap 的css和 ...
- php图片上传服务器
原理是把图片上传到服务器的某个目录,然后在把他的名字存入数据库,或者不需要数据库这部分也行.读取的时候直接读取名字. HTML提交表格 <form method="post" ...
- ios中摄像头/相册获取图片压缩图片上传服务器方法总结
本文章介绍了关于ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结,有需要了解的同学可以参考一下下. 这几天在搞iphone上面一个应用的开发,里面有需要摄像头/相册编程和图片上传的问 ...
- IOS 视频.图片上传服务器
//上传视频 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.requestSerializer. ...
随机推荐
- MFC ADO连接Oracle12c数据库 客户端环境搭建
ADO连接方式一:Provider=MSDAORA.1; 环境配置如下: 去官网下载ODAC121024Xcopy_32bit.zip安装 安装方式如下: (1)解压文件 (2)用命令行CD到该文件的 ...
- 深入研究 蒋金楠(Artech)老师的 MiniMvc(迷你 MVC),看看 MVC 内部到底是如何运行的
前言 跟我一起顺藤摸瓜剖析 Artech 老师的 MiniMVC 是如何运行的,了解它,我们就大体了解 ASP.NET MVC 是如何运行的了.既然是“顺藤摸瓜”,那我们就按照 ASP.NET 的执行 ...
- SQL Server里强制参数化的痛苦
几天前,我写了篇SQL Server里简单参数化的痛苦.今天我想继续这个话题,谈下SQL Server里强制参数化(Forced Parameterization). 强制参数化(Forced Par ...
- nginx的部署与发布
1.在http://nginx.org/en/download.html下载nginx.tar.gz包. 2.上传发送到服务器(wcp工具) 3.用tar -xf命令解压gz包 4.[配置安装变量]: ...
- C#对象与XMl文件之间的相互转换
C#提供三种序列化方式,分别为: 1.是使用BinaryFormatter进行串行化: 2.使用SoapFormatter进行串行化: 3.使用XmlSerializer进行串行化.其中对于Binar ...
- CentOS6.5菜鸟之旅:安装VirtualBox4.3
一.下载VirtualBox的RHEL软件库配置文件 cd /etc/yum.repos.d wget http://download.virtualbox.org/virtualbox/rpm/rh ...
- js代码中的闭包
作为一个后台开发人员了解前端非常重要,尤其是深处学校实验室做项目时前端把写好的代码直接给你,然后你在修改的时候.我经常做的就是修改前端的代码的HTML和后台交互的部分以及js的ajax部分,之后修改之 ...
- javascript之纯数字验证
现在有一个需求如下图: 产品经理说Card Number只能让输入数字(中间的空格是格式自加的,也是用js实现的),有时候我脑海中出现了个声音,啥玩意,加个type=number不就行了,事实发现图样 ...
- 领域驱动设计(DDD)实现之路
2004年,当Eric Evans的那本<领域驱动设计——软件核心复杂性应对之道>(后文简称<领域驱动设计>)出版时,我还在念高中,接触到领域驱动设计(DDD)已经是8年后的事 ...
- 重构第15天 移除重复的代码(Remove Duplication)
理解:移除重复的代码,顾名思义就是把多处重复的代码搬移到一个公共的地方,来减少代码量,提高代码可维护性. 详解:看下面的例子就很容易理解 重构前code using System; using Sys ...