通过相机捕获的图像质量丢失

Posted

技术标签:

【中文标题】通过相机捕获的图像质量丢失【英文标题】:Quality of image captured through camera is lost 【发布时间】:2016-02-18 12:57:25 【问题描述】:

我正在从相机捕获图像并将其发送到服务器。成功发布到服务器后,我将图像显示为相对布局中的背景。我的问题是图像质量丢失并且显示时图像被拉伸相对布局的背景。截图如下:

点击相机时

//On clicking Camera


 imgCamera.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
            // Checking camera availability
            if (!isDeviceSupportCamera()) 
                Toast.makeText(getApplicationContext(),
                        "Sorry! Your device doesn't support camera",
                        Toast.LENGTH_LONG).show();
                // will close the app if the device doesn't have camera
                finish();
             else 
                //cameraClick(view);
                captureImage();
            
        
    );

CaptureImage() 方法

private void captureImage() 
    Log.e("Capture Image", "Called");
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // creating Dir to save clicked Photo
    String root = Environment.getExternalStorageDirectory().toString();
    Log.e("root", root);
    String directory_path = root + "/cam_intent/";
    File myDir = new File(directory_path);
    myDir.mkdirs();
    // save clicked pic to given dir with given name
    File file = new File(myDir, "MyPhoto.jpg");
    fileUri = Uri.fromFile(file);
    Log.e("Uri of File", String.valueOf(fileUri));
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);

onActivityResult()

 @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    Log.e("onActivityResult", "Called");
    if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE && resultCode == RESULT_OK) 
        launchUploadActivity(true);
    

launchUploadActivity()

 private void launchUploadActivity(boolean isImage) 
    if (fileUri.getPath() != null) 
        // Displaying the image or video on the screen

        Log.e("Launch Upload Activity", "Called");
        previewMedia(isImage);
     else 
        Toast.makeText(getApplicationContext(),
                "Sorry, file path is missing!", Toast.LENGTH_LONG).show();
    

previewMedia()

 private void previewMedia(boolean isImage) 
    // Checking whether captured media is image or video
    if (isImage) 
        Log.e("Preview Media", "Called");          

        //Uploading image to server
        new UploadFileToServer().execute();         
    

上传文件到服务器

    private class UploadFileToServer extends AsyncTask<Void, Integer, String> 

    @Override
    protected void onPreExecute() 
        // setting progress bar to zero
        // progressBar.setProgress(0);
        super.onPreExecute();
    

    @Override
    protected void onProgressUpdate(Integer... progress) 
        // Making progress bar visible
        //progressBar.setVisibility(View.VISIBLE);
        //Making progress dialog visible
        progressDialog.show();

        // updating progress bar value
        // progressBar.setProgress(progress[0]);

        // updating percentage value
        //txtPercentage.setText(String.valueOf(progress[0]) + "%");
    

    @Override
    protected String doInBackground(Void... params) 
        return uploadFile();
    

    @SuppressWarnings("deprecation")
    private String uploadFile() 
        Log.e("upload File", "called");
        String responseString = null;

        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(file_upload_url);

        try 
            androidMultiPartEntity entity = new AndroidMultiPartEntity(
                    new AndroidMultiPartEntity.ProgressListener() 

                        @Override
                        public void transferred(long num) 
                            publishProgress((int) ((num / (float) totalSize) * 100));
                        
                    );


            // Adding file data to http body
            if (val == 0) 

                Log.e("val = ", String.valueOf(val));
                File sourceFile = new File(fileUri.getPath());
                if (sourceFile != null) 
                    Log.e("SoureFile", String.valueOf(sourceFile));
                    photosize = 0;
                    entity.addPart("image", new FileBody(sourceFile));
                 else 
                    photosize = 1;
                    Toast.makeText(ProfileActivity.this, "Please Upload Your Image", Toast.LENGTH_LONG).show();
                


             else 

                File sourceFile = new File(picturePath);
                if (sourceFile != null) 
                    photosize = 0;
                    entity.addPart("image", new FileBody(sourceFile));
                 else 
                    photosize = 1;
                    Toast.makeText(ProfileActivity.this, "Please Upload Your Image", Toast.LENGTH_LONG).show();
                

            

            totalSize = entity.getContentLength();
            Log.e("Total Size", String.valueOf(totalSize));
            httppost.setEntity(entity);

            // Making server call
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity r_entity = response.getEntity();

            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) 
                // Server response
                responseString = EntityUtils.toString(r_entity);
             else 
                responseString = "Error occurred! Http Status Code: "
                        + statusCode;
            

         catch (ClientProtocolException e) 
            responseString = e.toString();
         catch (IOException e) 
            responseString = e.toString();
        

        return responseString;

    

    @Override
    protected void onPostExecute(String result) 
        Log.e("UpLoad Server", "Response from server: " + result);
        try 
            JSONObject jsonObject = new JSONObject(result);
            String statusCode = jsonObject.getString("statusCode");
            if (statusCode.equals("200")) 
                JSONObject detail = jsonObject.getJSONObject("detail");
                String relativePath = detail.getString("relative_path");
                JSONObject uploadData = detail.getJSONObject("upload_data");
                String fileName = uploadData.getString("file_name");
                //Getting Base URL
                base_url = apiConfiguration.getApi();
                completeURL = base_url + relativePath + "/" + fileName;
                Log.e("Complete URl", completeURL);
                //Entering the new value of complete url in shared preference
                //editor.remove(Prefs_Registration.get_user_complete_url);
                editor.putString(Prefs_Registration.get_user_complete_url, completeURL);
                editor.commit();
                new GetBitmapFromURL().execute();
             else
                Toast.makeText(getApplicationContext(), "Image not uploaded", Toast.LENGTH_SHORT).show();
         catch (JSONException e) 
            e.printStackTrace();
        
        progressDialog.dismiss();

        // showing the server response in an alert dialog
        //showAlert(result);

        super.onPostExecute(result);
    

    /**
     * Method to show alert dialog
     */
    private void showAlert(String message) 
        AlertDialog.Builder builder = new AlertDialog.Builder(ProfileActivity.this);
        builder.setMessage(message)
                .setTitle("Response from Servers")
                .setCancelable(false)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() 
                    public void onClick(DialogInterface dialog, int id) 
                        // do nothing
                    
                );
        AlertDialog alert = builder.create();
        alert.show();
    


GetImageFromURL

 // Get Image from Thumbnail URL
class GetBitmapFromURL extends AsyncTask<String, String, Bitmap> 
    Bitmap myBitmap;

    @Override
    protected Bitmap doInBackground(String... strings) 
        URL url = null;
        try 
            url = new URL(completeURL);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            myBitmap = BitmapFactory.decodeStream(input);
         catch (MalformedURLException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        
        return myBitmap;

    

    @Override
    protected void onPostExecute(Bitmap bitmap) 

        Drawable dr = new BitmapDrawable(bitmap);
        Log.e("DrawableN", String.valueOf(dr));
        //Setting the image
        relativeLayout.setBackgroundDrawable(dr);
    

在 onPostExecute() 方法中,我将图像设置在相对布局的背景中。

XML

<RelativeLayout
    android:id="@+id/rel"
    android:layout_
    android:layout_
    android:layout_marginBottom="@dimen/margin10"
    android:layout_marginLeft="@dimen/margin10"
    android:layout_marginRight="@dimen/margin10"
    android:layout_marginTop="@dimen/margin10">

    <ImageView
        android:id="@+id/arrowProfile"
        android:layout_
        android:layout_
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:paddingLeft="@dimen/padding10"
        android:src="@drawable/back_signup" />

    <com.almabay.almachat.circularImageView.CircularImageView
        android:id="@+id/cam"
        android:layout_
        android:layout_
        android:layout_alignParentRight="true"
        android:paddingRight="@dimen/padding10"
        android:background="@drawable/camera1"/>

    <TextView
        android:id="@+id/userName"
        android:layout_
        android:layout_
        android:layout_above="@+id/status"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="@dimen/margin20"
        android:paddingLeft="@dimen/padding10"
        android:text="User Name"
        android:textColor="#ffffff"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/status"
        android:layout_
        android:layout_
        android:layout_alignParentBottom="true"
        android:paddingLeft="@dimen/padding10"
        android:text="Status of user"
        android:textColor="#ffffff" />
</RelativeLayout>

我将图像作为多部分发送到服务器。请告诉我如何在相对布局上渲染时保持图像的质量。

【问题讨论】:

您发布了或者更好的说法是倾倒了很多代码。我们应该挖掘这一切吗?只需将代码发布到所有内容即可。只是导致问题的一小段代码。 现在请检查代码。我只提到了我将图像发送到服务器并以相对布局显示的代码。 质量下降和拉伸是两件事。两者都真的发生了吗?我们可以看到拉伸是的。 我认为只有拉伸。 我不明白这与发布到服务器有什么关系。您不能只发布将图像文件放入图像视图的代码吗?否则请解释为什么它们首先连接。 【参考方案1】:

您的 ImageView 的纵横比应该等于捕获的图像的纵横比。

【讨论】:

我在相对布局的背景中显示图像。我没有在图像视图中显示它。 嗯,这也可能是个问题……我个人从来没有这样做过,但我猜长宽比应该匹配。

以上是关于通过相机捕获的图像质量丢失的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Camera 2 API Android 提高捕获图像的质量?

提高android应用程序中以编程方式捕获的图像的质量[重复]

如何在 Android 中提高 Camera 2 的图像质量?

使用自定义相机的图像质量很差

在 PhoneGap 中读取图像捕获文件

Camera 2 API 会降低拍摄后的质量