Как исправить растровое изменение размера захваченного изображения в Android - PullRequest
0 голосов
/ 04 ноября 2018

В приложении My Photo Editor для Android есть некоторые проблемы. После захвата изображения с камеры 20MegaPixel (5184x3880) через приложение я изменяю размер изображения с помощью растрового изображения на 15MegaPixel (4477 x 3351), а затем сохраняю изображение в папке Gallery / Photos в телефоне

Ниже приведен код HomeActivity:

package com.saashtechs.photoeditor;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.Objects;
import java.io.InputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;

import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

public class HomeActivity extends AppCompatActivity {

    private static final String TAG = "HomeActivity";
    private static final int GALLERY_RESULT = 1;
    private static final int CAMERA_RESULT = 2;
    private static final String FILE_PROVIDER_AUTHORITY = "com.saashtechs.photoeditor";
    private static final int CAMERA_PERMISSION_REQ_CODE = 1001;
    private static final int STORAGE_PERMISSION_REQ_CODE = 1002;
    private Uri imageToUploadUri;
    private String mCapturedImagePath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
    }

    public void openCamera(View view) {
        // check for camera permission if not granted before
        if (ContextCompat.checkSelfPermission(this, CAMERA) != PERMISSION_GRANTED) {
            String[] cameraPermission = {CAMERA};
            ActivityCompat.requestPermissions(this, cameraPermission, CAMERA_PERMISSION_REQ_CODE);
        } else {
            dispatchImageCaptureIntent();
        }
    }

    public void openGallery(View view) {
        // check for storage permission if not granted before
        if (ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
            String[] storagePermissions = {READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE};
            ActivityCompat.requestPermissions(this, storagePermissions, STORAGE_PERMISSION_REQ_CODE);
        } else {
            dispatchGalleryIntent();
        }
    }

    private void dispatchGalleryIntent() {
        Intent galleryIntent = new Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(galleryIntent, GALLERY_RESULT);
    }

    private void dispatchImageCaptureIntent() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (cameraIntent.resolveActivity(getPackageManager()) != null) {
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (photoFile != null) {
                Uri photoFileUri = FileProvider.getUriForFile(this, FILE_PROVIDER_AUTHORITY, photoFile);
                Log.d(TAG, "dispatchImageCaptureIntent:photoFileUri: " + photoFile.toString());
                //Add URI to imageToUploadUri. You forgot to add it.
                imageToUploadUri = photoFileUri;
                cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoFileUri);
                startActivityForResult(cameraIntent, CAMERA_RESULT);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case CAMERA_PERMISSION_REQ_CODE:
                if (grantResults[0] == PERMISSION_GRANTED) {
                    dispatchImageCaptureIntent();
                } else {
                    Toast.makeText(this, "Required camera permission not granted", Toast.LENGTH_SHORT).show();
                }
                break;

            case STORAGE_PERMISSION_REQ_CODE:
                if (grantResults[0] == PERMISSION_GRANTED) {
                    dispatchGalleryIntent();
                } else {
                    Toast.makeText(this, "Required storage permission not granted", Toast.LENGTH_SHORT)
                            .show();
                }
                break;

            default:
                throw new IllegalArgumentException("Unexpected request code");
        }
    }

    private File createImageFile() throws IOException {
        String timeStamp = DateFormat.getDateTimeInstance().format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(imageFileName, ".jpg", storageDir);
        mCapturedImagePath = image.getAbsolutePath();
        Log.d(TAG, "createImageFile: " + mCapturedImagePath);
        return image;
    }

    private Bundle uriToBundle(Uri imageUri) {
        Bundle bundle = new Bundle();
        bundle.putString(MainActivity.IMAGE_URI, imageUri.toString());
        return bundle;
    }

    public Bitmap resizeBitmap(Bitmap getBitmap, int maxSize) {
        int width = getBitmap.getWidth();//5184
        int height = getBitmap.getHeight();//3880
        double resized_image;

        if (width >= height && width > maxSize) {
            resized_image = width / height;
            width = maxSize;
            height = (int) (maxSize / resized_image);
        } else if (height >= width && height > maxSize) {
            resized_image = height / width;
            height = maxSize;
            width = (int) (maxSize / resized_image);
        }
        return Bitmap.createScaledBitmap(getBitmap, width, height, false);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == GALLERY_RESULT) {
                Uri imageUri = data.getData();
                startActivity(MainActivity.getIntent(this, uriToBundle(Objects.requireNonNull(imageUri))));
            } else if (requestCode == CAMERA_RESULT) {
                File imageFile = new File(mCapturedImagePath);
                Bitmap image = BitmapFactory.decodeFile(mCapturedImagePath);
                image = Bitmap.createScaledBitmap(image, 4477, 3351, false);
                image = resizeBitmap(image, 4477);
                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                image.compress(Bitmap.CompressFormat.JPEG, 100, bytes);

                try {
                    File file = new File(Environment.getExternalStorageDirectory() + File.separator + "filename.jpg");
                    boolean result;
                    result = file.createNewFile();
                    if (result) {
                        FileOutputStream fo = new FileOutputStream(imageFile);
                        fo.write(bytes.toByteArray());
                        fo.close();
                    }
                } catch(IOException ie) {
                    ie.printStackTrace();
                }

                startActivity(MainActivity.getIntent(this, uriToBundle(Objects.requireNonNull(imageToUploadUri))));
            }
        } else {
            Toast.makeText(this, "Image not loaded.", Toast.LENGTH_SHORT).show();
        }
    }

    public static Intent getIntent(Context context) {
        return new Intent(context, HomeActivity.class);
    }
}

Ниже приведен код MainActivity:

package com.saashtechs.photoeditor;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import com.adobe.creativesdk.aviary.AdobeImageIntent;

public class MainActivity extends AppCompatActivity {

  public static final String IMAGE_URI = "IMAGE_URI_KEY";

  private static final String TAG = "MainActivity";
  private static final int IMAGE_EDITOR_RESULT = 1;

  private ImageView mEditedImageView;

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mEditedImageView = (ImageView) findViewById(R.id.edited_image_view);

    Bundle extras = getIntent().getExtras();
    if (extras != null) {
      Uri imageUri = Uri.parse(getIntent().getExtras().getString(IMAGE_URI));
      Intent imageEditorIntent = new AdobeImageIntent.Builder(this).setData(imageUri).build();
      startActivityForResult(imageEditorIntent, IMAGE_EDITOR_RESULT);
      finish(); 
    }
  }

  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
      switch (requestCode) {
        case IMAGE_EDITOR_RESULT:
          Uri editedImageUri = data.getParcelableExtra(AdobeImageIntent.EXTRA_OUTPUT_URI);
          Log.d(TAG, "editedImageUri: " + editedImageUri.toString());
          Bundle extra = data.getExtras();
          if (extra != null) {
            boolean changed = extra.getBoolean(AdobeImageIntent.EXTRA_OUT_BITMAP_CHANGED);
            Log.d(TAG, "Image edited: " + changed);
            if (changed) {
              mEditedImageView.setImageURI(editedImageUri);
            }
          }
          break;

        default:
          throw new IllegalArgumentException("Unexpected request code");
      }
    }
  }

  public static Intent getIntent(Context context, Bundle bundle) {
    Intent intent = new Intent(context, MainActivity.class);
    if (bundle != null) {
      intent.putExtras(bundle);
    }
    return intent;
  }
}

Поэтому, когда я снимаю изображение, а затем, когда пользователь берется для редактирования приложения, это не так, он снова возвращает меня на домашнюю страницу после захвата изображения

Журнал ошибок:

2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  bitmap.size: 5184x3880
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  resize(15)
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  bitmap MP: 20, max MP: 15
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  Image must be resized! 20MP -> 15MP
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  target: 15MP = (4477x3351), max size: 4477
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  original: 20MP = (5184x3880)
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  maxWidth: 4477, maxHeight: 3351

Подскажите, пожалуйста, где я ошибаюсь?

Заранее спасибо

1 Ответ

0 голосов
/ 04 ноября 2018
if (extras != null) {
  Uri imageUri = Uri.parse(getIntent().getExtras().getString(IMAGE_URI));
  Intent imageEditorIntent = new AdobeImageIntent.Builder(this).setData(imageUri).build();
  startActivityForResult(imageEditorIntent, IMAGE_EDITOR_RESULT);
 // below line of code is not possible. your trying to receive result over 
  //here.  
 // . but your finishing it before it receives result
finish(); 
}

используйте приведенный ниже метод закрытия активности после получения данных. Передайте данные с установленным методом результата и затем закройте. поэтому ваша деятельность будет редактировать данные.
лучшее решение - вам не нужна эта промежуточная деятельность.

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
  switch (requestCode) {
    case IMAGE_EDITOR_RESULT:
      Uri editedImageUri = data.getParcelableExtra(AdobeImageIntent.EXTRA_OUTPUT_URI);
      Log.d(TAG, "editedImageUri: " + editedImageUri.toString());
      Bundle extra = data.getExtras();
      if (extra != null) {
        boolean changed = extra.getBoolean(AdobeImageIntent.EXTRA_OUT_BITMAP_CHANGED);
        Log.d(TAG, "Image edited: " + changed);
        if (changed) {
          mEditedImageView.setImageURI(editedImageUri);
        }
      }
      break;

    default:
      throw new IllegalArgumentException("Unexpected request code");
  }
}
}

В качестве руководства - приведенный ниже код очень плохая практика в Android

public static Intent getIntent(Context context, Bundle bundle) {
Intent intent = new Intent(context, MainActivity.class);
if (bundle != null) {
  intent.putExtras(bundle);
}
return intent;
}

Хорошая практика.

private void navigateToPhotoEditActivity(Context context, Bundle bundle) 
       {
    Intent intent = new Intent(context, MainActivity.class);
    if (bundle != null) {
      intent.putExtras(bundle);
    }
     startActivity(intent);
    }
...