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. ...
随机推荐
- Visual Studio .NET项目转换器(ProjectConverter)修改
Visual Studio .NET 项目转换器非常类似于ASP.NET版本转换器,区别在于它用于转换 Visual Studio 项目文件的版本.尽管在 .NET 框架的 1.0 版和 1.1 版之 ...
- 【翻译】C# Tips & Tricks: Weak References - When and How to Use Them
原文:C# Tips & Tricks: Weak References - When and How to Use Them Sometimes you have an object whi ...
- JavaScript 正则表达式提取感兴趣的字符串
var tdid="gov_sslim"; var reg=/(\w+)lim/; var name=tdid.match(reg); console.log(name[1]); ...
- 2013/11/21工作随笔-PHP开启多进程
今天被问到一个问题,php如何开启多进程才比较稳定. php开启多进程执行一个操作有哪些方法: 首先想到的是使用pcntl的fork 具体可以参考之前的文章:PHP的pcntl多进程 其次想到的方法是 ...
- Node.js面试题:侧重后端应用与对Node核心的理解
Node是搞后端的,不应该被被归为前端,更不应该用前端的观点去理解,去面试node开发人员.所以这份面试题大全,更侧重后端应用与对Node核心的理解. node开发技能图解 node 事件循环机制 起 ...
- [团队项目]sprint3 & 团队贡献分
希望各组认真准备,拿出最好的阵容最好的状态,展示一学期的学习与工作成果. 各组注意完成sprint3的博客,写上团队贡献分. 将演示PPT(如果有)和代码上传到github. 截止日期:2016.6. ...
- Math APP 2.0
首先,我们把这个软件理解成一个投入市场的.帮助小朋友进行算术运算练习的APP. 从质量保证的角度,有哪些需要改进的BUG? 从用户的角度(把自己当成小学生或真的请小学生帮忙),需要在哪些方面进行改进? ...
- Sql Server来龙去脉系列之二 框架和配置
本节主要讲维持数据的元数据,以及数据库框架结构.内存管理.系统配置等.这些技术点在我们使用数据库时很少接触到,但如果要深入学习Sql Server这一章节也是不得不看.本人能力有限不能把所有核心的知识 ...
- SeaJS 模块化加载框架使用
SeaJS 是一个遵循 CMD 规范的模块化加载框架 CommonJS,CMD,AMD等规范后文会提到,这里主要先了解如何在代码中使用. 如果你有使用过nodejs ,那么理解起来就容易多了. 我们通 ...
- 2015腾讯暑期实习生 Web前端开发 面试经历
[2015腾讯暑期实习生 Web前端开发 面试经历] 好吧,首先声明,我被刷了,应该是跪在二面 微信查到的面试状态一直呈现复试中 .. 整整四天了.. 看来是没希望了 不过也是一次经历,记录一下还是可 ...