我试图从设备相机拍摄照片或从图库中取出并通过排球将其上传到服务器 一切正常,但图像质量太差了
private void dispatchTakePictureIntent()
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent , CAMERA_REQUEST_CODE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data {
switch (requestCode) {
case CAMERA_REQUEST_CODE:
if ( resultCode == RESULT_OK){
Bundle bundle = data.getExtras();
bitmap = (Bitmap) bundle.get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
}
break;
和getParams方法:
byte[] a = convertBitmapToByteArrayUncompressed(bitmap);
params.put("img" , Base64.encodeToString(a , Base64.DEFAULT));
public static byte[] convertBitmapToByteArrayUncompressed(Bitmap bitmap){
ByteBuffer byteBuffer = ByteBuffer.allocate(bitmap.getByteCount());
bitmap.copyPixelsToBuffer(byteBuffer);
byteBuffer.rewind();
return byteBuffer.array();
}
答案 0 :(得分:3)
您必须使用多部分实体来发送图像而不进行压缩。使用多部分实体,您的图像质量也将得到保持。请按照此处使用截击发送图像
public class MultipartReq extends JsonObjectRequest {
private static final String FILE_PART_NAME = "file";
private static final String STRING_PART_NAME = "text";
private final File mFilePart;
//private final String mStringPart;
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
HttpEntity httpEntity;
Context context;
private Map<String, String> params;
public MultipartReq(Context context, int method, String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener, File file, Map<String, String> params) {
super(method, url, jsonRequest, listener, errorListener);
this.context = context;
mFilePart = file;
entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
this.params = params;
buildMultipartEntity();
httpEntity = entityBuilder.build();
}
private void buildMultipartEntity() {
try {
if (mFilePart.exists()) { entityBuilder.addBinaryBody(FILE_PART_NAME, mFilePart, ContentType.create(mimeType), mFilePart.getName());
}
try {
if(!params.isEmpty()){
for (String key: params.keySet()){
entityBuilder.addPart(key, new StringBody(params.get(key),ContentType.TEXT_PLAIN));
}
}
} catch (Exception e) {
VolleyLog.e("UnsupportedEncodingException");
}
} else {
ShowLog.e("no such file");
}
} catch (Exception e) {
ShowLog.e("UnsupportedEncodingException");
}
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
return params;
}
@Override
public String getBodyContentType() {
return httpEntity.getContentType().getValue();
}
@Override
public byte[] getBody() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
httpEntity.writeTo(bos);
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
@Override
protected void deliverResponse(JSONObject response) {
super.deliverResponse(response);
}
}
答案 1 :(得分:0)
来自Naugat拍照会有所不同。
创建图像文件拳头:
String mCurrentPhotoPath;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
然后发送拍照意图
static final int REQUEST_TAKE_PHOTO = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
...
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
在onActivity结果中检查RESULT_OK是否成功捕获。
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK)
您已经获得了图像路径。现在使用mCurrentPhotoPath
上传流程。
此外,您需要实现文件提供程序。
在你的清单中添加:
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider>
...
</application>
在资源目录中的XML中添加:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>
现在,您将从相机中获取完整尺寸的图像。
来源:https://developer.android.com/training/camera/photobasics.html
答案 2 :(得分:0)
使用getParcelableExtra()
,而不是getExtras()
用于小尺寸图片。
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("data");
如果您的图片太大,则必须压缩它们并发送到其他活动。然后,您可以获取压缩位图并在第二个活动中解压缩它。请尝试以下代码。
第1次活动
Intent intent = new Intent(this, SecondActivity.class);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPG, 100, stream);
byte[] bytes = stream.toByteArray();
intent.putExtra("bitmap",bytes);
第二项活动
byte[] bytes = getIntent().getByteArrayExtra("bitmap");
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);