1

カメラを初期化できるアプリを作成しています。写真を撮った後、写真をインポートして、ユーザーがさらに描画することができます。

コーディング:

クラスA:

   public OnClickListener cameraButtonListener = new OnClickListener()   
   {
      @Override
      public void onClick(View v) 
          {  
               vibrate();
               Toast.makeText(Doodlz.this, R.string.message_initalize_camera, Toast.LENGTH_SHORT).show();
               Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
               startActivityForResult(cameraIntent, CAMERA_REQUEST);               
           }      
   }; 

protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{
    super.onActivityResult(requestCode, resultCode, data);      

    if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) 
    {  
        Bitmap photo = (Bitmap) data.getExtras().get("data"); 
        Bitmap photocopy = photo.copy(Bitmap.Config.ARGB_8888, true);
        doodleView.get_camera_pic(photocopy);
    }
}

doodleView:

   public void get_camera_pic (Bitmap photocopy)
   {
    // get screen dimension first
      WindowManager wm = (WindowManager) context_new.getSystemService(Context.WINDOW_SERVICE);
      Display display = wm.getDefaultDisplay();
      final int screenWidth = display.getWidth();
      final int screenHeight = display.getHeight(); 
      bitmap = photocopy;
      bitmap = Bitmap.createScaledBitmap(bitmap, screenWidth, screenHeight, true);
      bitmapCanvas = new Canvas(bitmap);
      invalidate(); // refresh the screen      
   }

質問:

写真はカメラを使用して正常にキャプチャされ、ユーザーのために戻ることdoodleViewができます。ただし、インポートされた画像のサイズは非常に小さいため、サムネイルサイズだけです。(理由はわかりません)ので、スケールアップするのに疲れてしまい、解像度が非常に悪くなりました。

私の質問は、上記のコードを変更して、撮影した写真の寸法が画面の寸法に適合し、返される写真がサムネイルのようになるのではなく、画面の1:1になるようにするにはどうすればよいですか?(画面の1:1に合わせるのが最適です。元の写真サイズとしてインポートする場合、写真のサイズが画面よりも大きくなるため、完全に収まるように幅と高さの比率を変えて縮小し、歪める必要があります。画面)

ありがとう!!

4

2 に答える 2

3

これは、デフォルトのカメラアプリケーションでは正常です。フルサイズの画像を取得する方法は、結果をファイルに入れるようにカメラアクティビティに指示することです。最初にファイルを作成してから、次のようにカメラアプリケーションを起動します。

outputFileName = createImageFile(".tmp");
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outputFileName));
startActivityForResult(takePictureIntent, takePhotoActionCode);

次に、onActivityResultで、この画像ファイルを取得して操作できます。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (requestCode == takePhotoActionCode)
    {
        if (resultCode == RESULT_OK)
        {
            // NOTE: The intent returned might be NULL if the default camera app was used.
            // This is because the image returned is in the file that was passed to the intent.
                processPhoto(data);
        }
    }
}

processPhotoは次のようになります。

    protected void processPhoto(Intent i)
    {
        int imageExifOrientation = 0;

// Samsung Galaxy Note 2 and S III doesn't return the image in the correct orientation, therefore rotate it based on the data held in the exif.

        try
        {


    ExifInterface exif;
        exif = new ExifInterface(outputFileName.getAbsolutePath());
        imageExifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                                    ExifInterface.ORIENTATION_NORMAL);
    }
    catch (IOException e1)
    {
        e1.printStackTrace();
    }

    int rotationAmount = 0;

    if (imageExifOrientation == ExifInterface.ORIENTATION_ROTATE_270)
    {
        // Need to do some rotating here...
        rotationAmount = 270;
    }
    if (imageExifOrientation == ExifInterface.ORIENTATION_ROTATE_90)
    {
        // Need to do some rotating here...
        rotationAmount = 90;
    }
    if (imageExifOrientation == ExifInterface.ORIENTATION_ROTATE_180)
    {
        // Need to do some rotating here...
        rotationAmount = 180;
    }       

    int targetW = 240;
    int targetH = 320; 

    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(outputFileName.getAbsolutePath(), bmOptions);
    int photoWidth = bmOptions.outWidth;
    int photoHeight = bmOptions.outHeight;

    int scaleFactor = Math.min(photoWidth/targetW, photoHeight/targetH);

    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;

    Bitmap scaledDownBitmap = BitmapFactory.decodeFile(outputFileName.getAbsolutePath(), bmOptions);

    if (rotationAmount != 0)
    {
        Matrix mat = new Matrix();
        mat.postRotate(rotationAmount);
        scaledDownBitmap = Bitmap.createBitmap(scaledDownBitmap, 0, 0, scaledDownBitmap.getWidth(), scaledDownBitmap.getHeight(), mat, true);
    }       

    ImageView iv2 = (ImageView) findViewById(R.id.photoImageView);
    iv2.setImageBitmap(scaledDownBitmap);

    FileOutputStream outFileStream = null;
    try
    {
        mLastTakenImageAsJPEGFile = createImageFile(".jpg");
        outFileStream = new FileOutputStream(mLastTakenImageAsJPEGFile);
        scaledDownBitmap.compress(Bitmap.CompressFormat.JPEG, 75, outFileStream);
    }
    catch (Exception e)
    {
        e.printStackTrace();
            }
    }

注意すべき点の1つは、Nexusデバイスでは、呼び出しアクティビティは通常は破棄されないということです。ただし、Samsung Galaxy SIIIおよびNote2デバイスでは、通話アクティビティは破棄されます。したがって、outputFileNameをメンバー変数としてActivityに格納するだけで、アクティビティが終了したときに保存することを忘れない限り、カメラアプリが戻ったときにnullになります。とにかくそうするのは良い習慣ですが、これは私が以前に犯した間違いなので、私はそれについて言及したいと思いました。

編集:

あなたのコメントに関して、createImageFileは標準APIにありません、それは私が書いたものです(または私が借りたかもしれません:-)、私は覚えていません)、ここにcreateImageFile()のメソッドがあります:

    private File createImageFile(String fileExtensionToUse) throws IOException 
{

    File storageDir = new File(
            Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES
            ), 
            "MyImages"
        );      

    if(!storageDir.exists())
    {
        if (!storageDir.mkdir())
        {
            Log.d(TAG,"was not able to create it");
        }
    }
    if (!storageDir.isDirectory())
    {
        Log.d(TAG,"Don't think there is a dir there.");
    }

    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "FOO_" + timeStamp + "_image";

    File image = File.createTempFile(
        imageFileName, 
        fileExtensionToUse, 
        storageDir
    );

    return image;
}    
于 2013-02-09T14:40:13.133 に答える
1

画像全体にアクセスするにdata.getData()は、doodleViewでを使用してインテントURIにアクセスするか、(より適切に)追加のURIを指定してインテントに画像を渡すことにより、画像を保存するための独自のURIを提供する必要がありますEXTRA_OUTPUT

于 2013-02-09T12:28:27.270 に答える