做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. 【Thinking in Java-CHAPTER 1&&2】对象导论&&一切都是对象

    JAVA起源 从JDK诞生到现在已经有11年的时间了.沧海桑田一瞬间.转眼11年过去了,JDK已经发布了6个版本.在这11年里诞生了无数和Java相关的技术和标准.现在让我们进入时间隧道,重新回到19 ...

  2. linux 环境变量设置及查看

    1. 显示环境变量HOME $ echo $HOME /home/redbooks 2. 设置一个新的环境变量hello $ export HELLO="Hello!" $ ech ...

  3. VS2012下安装NuGet

    关于NuGet的两篇文章:MSDN上的使用 NuGet 管理项目库,和博客园dudu的程序员,用NuGet管理好你的包包. VS2012下安装NuGet 在工具菜单下选择“扩展和更新”. 选择“联机” ...

  4. fusioncharts图例(legend)属性

    图例用来在多系列图和混合图中将图形和对应的系列名称联系起来.      从v3.2开始,每个系列的名称前面会展示对应的icon图标,这些图标具有交互作用,用户可以通过点击这些图标来显示或者隐藏对应的数 ...

  5. java中产生对象的两种方式

    /* * 普通new对象的过程! */ Person pp = new Person(); System.out.println(pp); /* * 利用代用参数的构造器产生对象实例! * 首先获得相 ...

  6. Cwinux简介及用法简述

    我在我的个人博客上发表了一篇文章 Cwinux简介及用法简述 http://apprentice89.com/cwinux_introduction_and_use/

  7. 编写高质量JS代码的68个有效方法(八)

    [20141227]编写高质量JS代码的68个有效方法(八) *:first-child { margin-top: 0 !important; } body>*:last-child { ma ...

  8. Hadoop第10周练习—Mahout部署及进行20newsgroup数据分析例子

    :搭建Mahout环境 :运行20newsgroup 内容 运行环境说明 1.1 硬软件环境 线程,主频2.2G,6G内存 l  虚拟软件:VMware® Workstation 9.0.0 buil ...

  9. LeetCode——Serialize and Deserialize Binary Tree

    Description: Serialization is the process of converting a data structure or object into a sequence o ...

  10. python第三方模块精选

    python不但有着强大丰富的“内置电池”,同样的,第三方模块也是非常的多.目前收集了requests.paramiko.pymsql,以后会陆续添加: 一.requests Python标准库中提供 ...