Xamarin.Android 压缩图片并上传到WebServices

简介:   随着手机的拍照像素越来越高,导致图片赞的容量越来越大,如果上传多张图片不进行压缩、质量处理很容易出现OOM内存泄漏问题。  最近做了一个项目,向webservices上传多张照片,但是项目部署出来就会出现闪退现象,后来经行调试发现图片没有进行压缩,一张图片大小为2M,然而webservices没法接搜多个大图片,所以需要改下配置文件,我这里改为40M。

  随着手机的拍照像素越来越高,导致图片赞的容量越来越大,如果上传多张图片不进行压缩、质量处理很容易出现OOM内存泄漏问题。

  最近做了一个项目,向webservices上传多张照片,但是项目部署出来就会出现闪退现象,后来经行调试发现图片没有进行压缩,一张图片大小为2M,然而webservices没法接搜多个大图片,所以需要改下配置文件,我这里改为40M。

  <system.web> 
    <httpRuntime maxRequestLength = "40960" useFullyQualifiedRedirectUrl="true"/>
  </system.web>

   这里改好后发现上传图片还是有问题,后来经过一步步调试发现将本地图片转换成Bitmap后没有清空,然后一直存放在内存中,导致内存泄漏。只要把转换完的Bitmap清空一下就好了。

        /// <summary>
        /// 图片转换成String流
        /// </summary>
        /// <param name="file_path">文件名(不带file://)</param>
        /// <returns></returns>
        public static string ImageToString(string file_path)
        {
            //待上传图片路径
            //string uploadFile = file_path;

            //转化成文件  

            //System.IO.FileInfo imgFile = new System.IO.FileInfo(uploadFile);



            ////文件转化成字节
            //byte[] imgByte = new byte[imgFile.Length];

            //////读文件               
            //System.IO.FileStream imgStream = imgFile.OpenRead();

            //////文件写入到字节数组
            //imgStream.Read(imgByte, 0, Convert.ToInt32(imgFile.Length));

            //////字节数组转换成String类型
            //string by = Convert.ToBase64String(imgByte);

            ////上传到服务器 后面是文件名 
            ////fileUp.UpdateFile(imgByte, Guid.NewGuid() + ".png");

            //return imgByte;  

            Bitmap bitmap = BitmapFactory.DecodeFile(file_path);        //将图片文件转换成bitmap 格式:/storage/emulated/0/DCIM/Camera/IMG_20180425_105725.jpg

            string bitstring = BitmapToString(bitmap); 
            bitmap = null;              //一定要清空,否则会导致OOM问题
            GC.Collect();
            return bitstring; 
        } 

        /// <summary>
        /// 图片缩放处理
        /// </summary>
        /// <param name="bgimage">Bitmap文件</param>
        /// <param name="newWidth">新图片宽度</param>
        /// <param name="newHeight">新图片高度</param>
        /// <returns></returns>
        public static Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight)
        {
            // 获取这个图片的宽和高
            float width = bgimage.Width;
            float height = bgimage.Height;
            // 创建操作图片用的matrix对象
            Matrix matrix = new Matrix();
            // 计算宽高缩放率
            float scaleWidth = ((float)newWidth) / width;
            float scaleHeight = ((float)newHeight) / height;
            // 缩放图片动作
            matrix.PostScale(scaleWidth, scaleHeight);
            Bitmap bitmap = Bitmap.CreateBitmap(bgimage, 0, 0, (int)width,
                            (int)height, matrix, true);
            return bitmap;
        }

        static  string  BitmapToString(Bitmap bitmap)
        {
            Bitmap bit = zoomImage(bitmap, 750, 1000);//小图
                                                   //质量压缩
            //MemoryStream stream = new MemoryStream();
            //bit.Compress(Bitmap.CompressFormat.Jpeg, 50, stream);
            //byte[] bitmapData = stream.ToArray();
            //Bitmap map = BitmapFactory.DecodeByteArray(bitmapData, 0, bitmapData.Length);
            //btn_imagetwo.SetImageBitmap(map);
            //Bitmap im = zoomImage(bitmap, 800, 900);//大图
            MemoryStream big_stream = new MemoryStream();
            bit.Compress(Bitmap.CompressFormat.Jpeg, 80, big_stream);
            byte[] big_bitmapData = big_stream.ToArray();
            return  Convert.ToBase64String(big_bitmapData);
        }        

  webservices接受进行保存图片:

     private String ImagePath = "/HandlerImages/";

        /// <summary>
        /// 上传图片
        /// </summary>
        /// <param name="content">图片字符流</param>
        /// <param name="pathandname">图片名称</param>
        /// <returns></returns>
        
        [WebMethod]
        public bool UpdateFile(string content, string pathandname)
        {
            //保存图片路径
            string FilePath = Server.MapPath(ImagePath);
            //判断路径是否存在
            if (!Directory.Exists(FilePath))
            {
                //创建路径
                Directory.CreateDirectory(FilePath);
            }

            string SaveFilePath = Path.Combine(FilePath, pathandname);
            byte[] fileBytes;
            try
            {
                fileBytes = Convert.FromBase64String(content);
                MemoryStream memoryStream = new MemoryStream(fileBytes); //1.定义并实例化一个内存流,以存放提交上来的字节数组。  
                FileStream fileUpload = new FileStream(SaveFilePath, FileMode.Create); ///2.定义实际文件对象,保存上载的文件。  
                memoryStream.WriteTo(fileUpload); ///3.把内存流里的数据写入物理文件  
                memoryStream.Close();
                fileUpload.Close();
                fileUpload = null;
                memoryStream = null;
                return true;
            }
            catch
            {
                return false;
            }
        }

调用webservices上传图片:

MyWebService service = new MyWebService(); 
service.UpdateFile(ImageToByte("/storage/emulated/0/DCIM/Camera/IMG_20180425_105725.jpg"),Guid.NewGuid().ToString() + ".jpg");

 

目录
相关文章
|
4月前
|
XML Java Android开发
Android Studio App开发之对图片进行简单加工(包括放缩,旋转等等 附源码)
Android Studio App开发之对图片进行简单加工(包括放缩,旋转等等 附源码)
87 0
|
4月前
|
XML Java Android开发
Android Studio App开发之使用相机拍摄照片和从相册中选取图片(附源码 超详细必看)
Android Studio App开发之使用相机拍摄照片和从相册中选取图片(附源码 超详细必看)
603 0
|
6天前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
37 20
Android经典面试题之图片Bitmap怎么做优化
|
4月前
|
Android开发
Android通过手势(多点)缩放和拖拽图片
Android通过手势(多点)缩放和拖拽图片
42 4
|
4月前
|
Java Android开发
android 下载图片的问题
android 下载图片的问题
35 3
|
1月前
|
数据处理 开发工具 数据安全/隐私保护
Android平台RTMP推送|轻量级RTSP服务|GB28181接入之文字、png图片水印的精进之路
本文探讨了Android平台上推流模块中添加文字与PNG水印的技术演进。自2015年起,为了满足应急指挥及安防领域的需求,逐步发展出三代水印技术:第一代为静态文字与图像水印;第二代实现了动态更新水印内容的能力,例如实时位置与时间信息;至第三代,则优化了数据传输效率,直接使用Bitmap对象传递水印数据至JNI层,减少了内存拷贝次数。这些迭代不仅提升了用户体验和技术效率,也体现了开发者追求极致与不断创新的精神。
|
1月前
|
自然语言处理 定位技术 API
Android经典实战之如何获取图片的经纬度以及如何根据经纬度获取对应的地点名称
本文介绍如何在Android中从图片提取地理位置信息并转换为地址。首先利用`ExifInterface`获取图片内的经纬度,然后通过`Geocoder`将经纬度转为地址。注意操作需在子线程进行且考虑多语言支持。
110 4
|
1月前
|
XML 前端开发 Android开发
Android经典实战之Kotlin中实现圆角图片和圆形图片
本文介绍两种实现圆角图像视图的方法。第一种是通过自定义Kotlin `AppCompatImageView`,重写`onDraw`方法使用`Canvas`和`Path`进行圆角剪裁。第二种利用Android Material库中的`ShapeableImageView`,简单配置即可实现圆角效果。两种方法均易于实现且提供动态调整圆角半径的功能。
29 0
|
3月前
|
JSON 编解码 Apache
Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
43 1
|
3月前
|
Java Android开发
18. 【Android教程】图片控件 ImageView
18. 【Android教程】图片控件 ImageView
50 4