做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拍照选择图片上传服务器自定义控件的更多相关文章

  1. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  2. HTML5 Plus 拍照或者相册选择图片上传

    HBuilder+HTML5 Plus+MUI实现拍照或者相册选择图片上传,利用HTML5 Plus的Camera.Gallery.IO.Storage和Uploader来实现手机APP拍照或者从相册 ...

  3. H5拍照、选择图片上传组件核心

    背景 前段时间项目重构,改成SSR的项目,但之前用的图片选择上传组件不支持SSR(server-side-render).遂进行了调研,发现很多的工具.但有的太大,有的使用麻烦,有的不满足使用需求.决 ...

  4. [转]微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传

    本文转自:http://blog.csdn.net/qq_31383345/article/details/53014610 今天遇到微信小程序的用户头像设置功能,做笔记. 先上gif: 再上代码: ...

  5. 微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传

    1.index.wxml <!--index.wxml--> <button style="margin:30rpx;" bindtap="choose ...

  6. MVC4中基于bootstrap和HTML5的图片上传Jquery自定义控件

    场景:mvc4中上传图片,批量上传,上传前浏览,操作.图片进度条. 解决:自定义jquery控件 没有解决:非图片上传时,会有浏览样式的问题; 解决方案; 1.样式 – bootstrap 的css和 ...

  7. php图片上传服务器

    原理是把图片上传到服务器的某个目录,然后在把他的名字存入数据库,或者不需要数据库这部分也行.读取的时候直接读取名字. HTML提交表格 <form method="post" ...

  8. ios中摄像头/相册获取图片压缩图片上传服务器方法总结

    本文章介绍了关于ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结,有需要了解的同学可以参考一下下.     这几天在搞iphone上面一个应用的开发,里面有需要摄像头/相册编程和图片上传的问 ...

  9. IOS 视频.图片上传服务器

    //上传视频 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];    manager.requestSerializer. ...

随机推荐

  1. MFC ADO连接Oracle12c数据库 客户端环境搭建

    ADO连接方式一:Provider=MSDAORA.1; 环境配置如下: 去官网下载ODAC121024Xcopy_32bit.zip安装 安装方式如下: (1)解压文件 (2)用命令行CD到该文件的 ...

  2. 深入研究 蒋金楠(Artech)老师的 MiniMvc(迷你 MVC),看看 MVC 内部到底是如何运行的

    前言 跟我一起顺藤摸瓜剖析 Artech 老师的 MiniMVC 是如何运行的,了解它,我们就大体了解 ASP.NET MVC 是如何运行的了.既然是“顺藤摸瓜”,那我们就按照 ASP.NET 的执行 ...

  3. SQL Server里强制参数化的痛苦

    几天前,我写了篇SQL Server里简单参数化的痛苦.今天我想继续这个话题,谈下SQL Server里强制参数化(Forced Parameterization). 强制参数化(Forced Par ...

  4. nginx的部署与发布

    1.在http://nginx.org/en/download.html下载nginx.tar.gz包. 2.上传发送到服务器(wcp工具) 3.用tar -xf命令解压gz包 4.[配置安装变量]: ...

  5. C#对象与XMl文件之间的相互转换

    C#提供三种序列化方式,分别为: 1.是使用BinaryFormatter进行串行化: 2.使用SoapFormatter进行串行化: 3.使用XmlSerializer进行串行化.其中对于Binar ...

  6. CentOS6.5菜鸟之旅:安装VirtualBox4.3

    一.下载VirtualBox的RHEL软件库配置文件 cd /etc/yum.repos.d wget http://download.virtualbox.org/virtualbox/rpm/rh ...

  7. js代码中的闭包

    作为一个后台开发人员了解前端非常重要,尤其是深处学校实验室做项目时前端把写好的代码直接给你,然后你在修改的时候.我经常做的就是修改前端的代码的HTML和后台交互的部分以及js的ajax部分,之后修改之 ...

  8. javascript之纯数字验证

    现在有一个需求如下图: 产品经理说Card Number只能让输入数字(中间的空格是格式自加的,也是用js实现的),有时候我脑海中出现了个声音,啥玩意,加个type=number不就行了,事实发现图样 ...

  9. 领域驱动设计(DDD)实现之路

    2004年,当Eric Evans的那本<领域驱动设计——软件核心复杂性应对之道>(后文简称<领域驱动设计>)出版时,我还在念高中,接触到领域驱动设计(DDD)已经是8年后的事 ...

  10. 重构第15天 移除重复的代码(Remove Duplication)

    理解:移除重复的代码,顾名思义就是把多处重复的代码搬移到一个公共的地方,来减少代码量,提高代码可维护性. 详解:看下面的例子就很容易理解 重构前code using System; using Sys ...