在安卓开发中有一个非常常用的功能就是上传图片了,但往往图片较大,而安卓屏幕较小,不需要过高的分辨率,我们需要压缩一下在发送到服务器这样可以减少服务器的存储压力和减少网络的使用。
下面是服务端的代码就是要获取到一个IFormFile对象就行了,这样就能或得到流,然后我们通过流写到服务器所在的机器硬盘里就可以了。文件名我们用随机数生成就可以了。
using System;
using System.IO;
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Secondhandmarket.Controllers
{
[Route("api/[controller]")]
[Controller]
public class UploadController : Controller
{
[HttpPost("load")]
[HttpPost]
public ActionResult UploadImg([FromForm(Name = "file")] IFormFile file)
{
//获得当前项目wwwroot/image的绝对路径
var appPath = AppContext.BaseDirectory.Split("\\bin\\")[0] + "/wwwroot/image/";
try
{
if (file != null)
{
string url = appPath + "/" + createSmallAbc()+".png";
//文件后缀
var fileExtension = Path.GetExtension(file.FileName);
//判断后缀是否是图片
const string fileFilt = ".gif|.jpg|.jpeg|.png";
if (fileFilt.IndexOf(fileExtension.ToLower(), StringComparison.Ordinal) <= -1)
{
return null;
}
//将文件写入磁盘
using (FileStream fs = System.IO.File.Create(url))
{
file.CopyTo(fs);
fs.Flush();
return Json(new { msg = "success" });
}
}
return Json(new { msg = "faild" });
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return Json(new { msg = "faild"});
}
}
/**
*生成随机数
*/
private string createSmallAbc()
{
StringBuilder stringBuilder = new StringBuilder("");
for (int i = 0; i < 4; i++)
{
Random random = new Random(Guid.NewGuid().GetHashCode());
int num = random.Next(97, 123);
string abc = Convert.ToChar(num).ToString();
stringBuilder.Append(abc);
}
return stringBuilder.ToString();
}
}
}
[FromForm(Name = "file")]表示我们要接受表单里的文件数据,所以我们在安卓端发送表单post请求就可以了
private static void uploadImage(String url,File file){
String imagePath = file.getAbsoluteFile().toString();
Log.d(TAG,"file.getPah:"+imagePath);
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody image = RequestBody.create(MediaType.parse("image/jpg"), file);
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", imagePath, image)
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String responseStr = response.body().string();
Log.d(TAG, "onResponse: "+responseStr);
}
});
}
private static void uploadImage(String url, String imagePath,float desWidth) {
Log.d("imagePath", imagePath);
//下面这两句是用于压缩的,不需要的话可以直接删除掉
Bitmap compressbitmap = CompressImageUtil.compressImageFromFile(imagePath,desWidth);
File file = CompressImageUtil.compressImage(compressbitmap);
//调用重载,发送post请求
uploadImage(url,file);
}
我们用了OkHttp3发送请求,这样后台就能收到了。
下面是压缩
package com.example.myapplication.util;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class CompressImageUtil {
public static Bitmap compressImageFromFile(String srcPath, float desWidth) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;//只读边,不读内容
Bitmap bitmap;
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
float desHeight = desWidth * h / w;
int be = 1;
if (w > h && w > desWidth) {
be = (int) (newOpts.outWidth / desWidth);
} else if (w < h && h > desHeight) {
be = (int) (newOpts.outHeight / desHeight);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//设置采样率
// newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默认的,可不设
newOpts.inPurgeable = true;// 同时设置才会有效
newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return bitmap;
}
/**
* 压缩图片(质量压缩)
*
* @param image
*/
public static File compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();//重置baos即清空baos
options -= 10;//每次都减少10
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
long length = baos.toByteArray().length;
}
File file = new File(Environment.getExternalStorageDirectory() + "/temp.png");
try {
FileOutputStream fos = new FileOutputStream(file);
try {
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return file;
}
}
我们压缩后最后得到的还是file将这个file扔给服务器就可以了。