2012-07-28 94 views
0

我正在研究一個應用程序,需要在拍攝後訪問圖片中的像素數組。主要活動如下。我擁有大量的Java體驗,但過去在屏幕上顯示圖像的經歷非常有限。我看到字節數組傳遞給圖片回調方法,但我不知道它是如何格式化的。如何獲取包含捕獲圖像中的RGB分量的像素陣列?我試圖通過堆棧溢出論壇找到這個,但是我得到了幾百頁的結果,並且只搜索了前10個左右,所以我很抱歉,如果這已經被問到,我只是沒有看到它。從使用攝像頭拍攝的圖像中檢索像素陣列

public class ConverterActivity extends Activity 
{ 
    private Camera mCamera; 
    private CameraPreview mPreview; 
private PictureCallback mPicture = new PictureCallback() { 
private String TAG; 
@Override 
public void onPictureTaken(byte[] data, Camera camera) { 
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); 
if (pictureFile == null){ 
// Log.d(TAG, "Error creating media file, check storage permissions: " + 
// e.getMessage()); 
return; 
} 
try { 
FileOutputStream fos = new FileOutputStream(pictureFile); 
fos.write(data); 
fos.close(); 
} catch (FileNotFoundException e) { 
Log.d(TAG, "File not found: " + e.getMessage()); 
} catch (IOException e) { 
Log.d(TAG, "Error accessing file: " + e.getMessage()); 
} 
} 
}; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

// Add a listener to the Capture button 
Button captureButton = (Button) findViewById(R.id.button_capture); 
captureButton.setOnClickListener(
new View.OnClickListener() { 
@Override 
public void onClick(View v) { 
// get an image from the camera 
mCamera.takePicture(null, null, mPicture); 
} 
} 
); 
     // Create an instance of Camera 
     mCamera = Camera.open(this.getBackCamera()); 
     // Create our Preview view and set it as the content of our activity. 
     mPreview = new CameraPreview(this, mCamera); 
     FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
     preview.addView(mPreview); 
} 
@Override 
    protected void onPause() 
    { 
     super.onPause(); 
     releaseCamera();    // release the camera immediately on pause event 
    } 
    private void releaseCamera(){ 
     if (mCamera != null){ 
      mCamera.release();  // release the camera for other applications 
      mCamera = null; 
     } 
    } 
public static final int MEDIA_TYPE_IMAGE = 1; 
public static final int MEDIA_TYPE_VIDEO = 2; 
/** Create a file Uri for saving an image or video */ 
private static Uri getOutputMediaFileUri(int type){ 
return Uri.fromFile(getOutputMediaFile(type)); 
} 
/** Create a File for saving an image or video */ 
private static File getOutputMediaFile(int type){ 
// To be safe, you should check that the SDCard is mounted 
// using Environment.getExternalStorageState() before doing this. 
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp"); 
// This location works best if you want the created images to be shared 
// between applications and persist after your app has been uninstalled. 
// Create the storage directory if it does not exist 
if (! mediaStorageDir.exists()){ 
if (! mediaStorageDir.mkdirs()){ 
Log.d("MyCameraApp", "failed to create directory"); 
return null; 
} 
} 
// Create a media file name 
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
File mediaFile; 
if (type == MEDIA_TYPE_IMAGE){ 
mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
"IMG_"+ timeStamp + ".jpg"); 
} else if(type == MEDIA_TYPE_VIDEO) { 
mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
"VID_"+ timeStamp + ".mp4"); 
} else { 
return null; 
} 
return mediaFile; 
} 
public int getBackCamera() 
{ 
int numCameras = Camera.getNumberOfCameras(); 
CameraInfo cInfo = new CameraInfo(); 
for (int i = 0; i < numCameras; i++) 
{ 
Camera.getCameraInfo(i, cInfo); 
if (cInfo.facing == CameraInfo.CAMERA_FACING_BACK) 
{ 
return i; 
} 
} 
return -1; 
} 
} 

回答

0

如果使用這樣的代碼拍照:

imgFile = new File(Environment.getExternalStorageDirectory() + "/somefolder/" + name + ".jpg"); 

    String fileName = imgFile.getAbsolutePath(); 

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(fileName))); 

    startActivityForResult(intent, REQUEST_FROM_CAMERA); 

那麼你應該可以,當你得到的結果,從這一意圖回來,用這樣的代碼來訪問位圖

if (imgFile.exists()) { 
     String fileName = file.getAbsolutePath(); 
     BitmapFactory.Options opts = new BitmapFactory.Options(); 
     Bitmap bm; 

     opts.inJustDecodeBounds = false; 

     bm = BitmapFactory.decodeFile(fileName, opts); 
     return bm; 
    } 
    else return null; 

然後你可以使用bitmapfactory工具,如壓縮到流,然後 轉換爲byte []

ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    bm.compress(Bitmap.CompressFormat.JPEG, 100, stream); // 100 = max quality 
    byte[] byteArray = stream.toByteArray(); 
+0

謝謝,雖然我有幾個問題,但我對android和圖像很不熟悉。首先是什麼代碼替換?只是拍照並保存?還是取代了相機預覽?那麼字節數組是如何表示像素的?如何使用您提供的內容檢索特定像素的RGB分量? – 2012-07-29 03:23:40

+0

您還必須使用bitmapfactory設置組件類型。 options.inPreferredConfig = Bitmap.Config.RGB_565將其設置爲每個組件2和3個像素,而ARGB_8888將其設置爲alpha,紅色,綠色和藍色中的每個像素8位。我還沒有嘗試過,但我想象你可以索引到組件的這個字節數組,然後將x和y計算爲單個整數 – Martin 2012-07-30 03:57:27

+0

非常感謝。我很抱歉不得不提出另一個問題,但是你是否介意在最後一句中澄清你的意思? 「我沒有嘗試過,但我想象你可以索引到組件上的字節數組,然後將x和y計算爲單個整數」我不明白你是通過索引到組件上的字節數組還是什麼你的意思是「將x和y計算成單個整數」 – 2012-07-30 04:12:55