安卓:JPEG保存的摄像头看上去损坏摄像头、JPEG

2023-09-13 00:56:07 作者:限量版禽兽丶

我正在写一个Android应用程序,当用户点击一个按钮保存在相机的JPEG快照。不幸的是,当我在看的JPEG文件我的code是节省的外观损坏。这似乎是我的呼吁引起parameters.set previewSize(见下文code段) - 如果我删除然后将图像保存罚款;然而,没有它,我不能设置preVIEW大小和setDisplayOrientation也似乎没有任何效果离不开它了。

我的应用程序的目标是API等级8(Android 2.2的),和我调试上的HTC Desire HD。不太清楚我在做什么错在这里...任何帮助将非常AP preciated!

干杯, 斯科蒂

 公共无效surfaceChanged(SurfaceHolder持有人,INT格式,INT W,INT高){
    //现在的尺寸是已知的,设置相机参数,并开始
    //在preVIEW。
    Camera.Parameters参数= mCamera.getParameters();
    Camera.Size大小= getBest previewSize(W,H);

    //下一个调用是为了preVIEW大小进行设置,并
    // setDisplayOrientation生效...
    //不幸的是它也造成JPEG要创建错误
    parameters.set previewSize(size.width,size.height);

    parameters.setPictureFormat(ImageFormat.JPEG);
    mCamera.setParameters(参数);
    mCamera.setDisplayOrientation(90);

    mCamera.start preVIEW();

}

//这是快照按钮事件处理程序
公共无效onSnapshotButtonClick(查看目标){
    //无效android.hardware.Camera.takePicture(ShutterCallback快门,
    // PictureCallback原料,PictureCallback JPEG)
    米preview.mCamera.takePicture(NULL,NULL,mPictureCallback);
}


//这节省了相机快照作为SD卡上的JPEG文件
Camera.PictureCallback mPictureCallback =新Camera.PictureCallback(){
    公共无效onPictureTaken(byte []的为imageData,摄像机C){

        如果(为imageData!= NULL){
            FileOutputStream中outStream = NULL;
            尝试 {
                字符串myJpgPath =的String.Format(
                        /sdcard/%d.jpg,System.currentTimeMillis的());

                outStream =新的FileOutputStream(myJpgPath);
                outStream.write(为imageData);
                outStream.close();
                Log.d(TestApp,onPictureTaken  - 写字节
                        + imageData.length);

                c.start preVIEW();
                Toast.makeText(getApplicationContext()的String.Format(%书面,myJpgPath),Toast.LENGTH_SHORT).show();

            }赶上(FileNotFoundException异常E){
                e.printStackTrace();
            }赶上(IOException异常E){
                e.printStackTrace();
            } 最后 {
            }
        }
    }
};
 

解决方案

另一个解决办法是符合preVIEW和图像大小之间的纵横比(即一套previewSize(W1,H1); setPictureSize(W2, H2)与W1 / H1〜W2 / H2(小的差别似乎是确定))。例如。对于Desire HD的小号W1 = 800,H1 ​​= 480,W2 = 2592,H2 = 1552的作品以及W1 = 960,H1 ​​= 720,H2 = 2592,H2 =(1952年第,如果你不介意的扭曲图像;-)

I'm writing an Android application that saves a JPEG snapshot from the camera when the user clicks a button. Unfortunately, when I look at the JPEG file my code is saving looks corrupted. It appears to be caused by my call to parameters.setPreviewSize (see code snippet below) - if I remove that then the image saves fine; however without it I can't set the preview size and setDisplayOrientation also appears to have no effect without it.

iPhone 14 Pro升4800万像素,摄像头更厚了

My app is targeting API Level 8 (Android 2.2), and I'm debugging on an HTC Desire HD. Not quite sure what I'm doing wrong here... any help would be very much appreciated!

Cheers, Scottie

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    Camera.Parameters parameters = mCamera.getParameters();        
    Camera.Size size = getBestPreviewSize(w,h);

    // This next call is required in order for preview size to be set and
    // setDisplayOrientation to take effect...
    // Unfortunately it's also causing JPEG to be created wrong
    parameters.setPreviewSize(size.width, size.height);

    parameters.setPictureFormat(ImageFormat.JPEG);
    mCamera.setParameters(parameters);
    mCamera.setDisplayOrientation(90);

    mCamera.startPreview();

}

// This is the snapshot button event handler
public void onSnapshotButtonClick(View target) {
    //void android.hardware.Camera.takePicture(ShutterCallback shutter, 
    //                              PictureCallback raw, PictureCallback jpeg)
    mPreview.mCamera.takePicture(null, null, mPictureCallback);
}


// This saves the camera snapshot as a JPEG file on the SD card
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] imageData, Camera c) {

        if (imageData != null) {
            FileOutputStream outStream = null;
            try {
                String myJpgPath = String.format(
                        "/sdcard/%d.jpg", System.currentTimeMillis());

                outStream = new FileOutputStream(myJpgPath);
                outStream.write(imageData);
                outStream.close();
                Log.d("TestApp", "onPictureTaken - wrote bytes: "
                        + imageData.length);

                c.startPreview();
                Toast.makeText(getApplicationContext(), String.format("%s written", myJpgPath), Toast.LENGTH_SHORT).show();

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
        }
    }
};

解决方案

Another workaround is to match the aspect ratio between preview and picture sizes (i.e. setPreviewSize(w1,h1); setPictureSize(w2,h2) with w1/h1 ~ w2/h2 (small differences seem to be ok)). E.g. for Desire HD S w1=800,h1=480, w2=2592,h2=1552 works as well as w1=960,h1=720,h2=2592,h2=1952 (if you don't mind distorted images ;-)