কীভাবে অ্যান্ড্রয়েড ক্যামেরা ওরিয়েন্টেশন সঠিকভাবে সেট করবেন?


90

আমি অ্যান্ড্রয়েডে ডিভাইস ওরিয়েন্টেশন অনুযায়ী ক্যামেরা ওরিয়েন্টেশন সেট করতে চাই তবে কিছুই কাজ করছে বলে মনে হচ্ছে না। আমি সারফেসটি পাশাপাশি ক্যামেরা প্যারামিটারগুলি ঘোরানোর চেষ্টা করেছি তবে প্রতিকৃতি মোডে ক্যামেরা প্রিভিউ সবসময় উল্টোদিকে আসে। এটি সঠিক হওয়ার জন্য আমার এটিকে 90 ডিগ্রি ঘড়ির কাঁটা দিয়ে ঘোরানো দরকার। আমি এখনই ব্যবহার করছি এমন কোডটি যা কেবল আড়াআড়ি মোডে কাজ করে।

    SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
        camera.release();
        camera = null;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {          
        initCamera();           
    }

    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.2;
        double targetRatio = (double) w / h;
        if (sizes == null)
            return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            Log.d(TAG, "Checking size " + size.width + "w " + size.height
                    + "h");
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the
        // requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Camera.Parameters parameters = camera.getParameters();

        List<Size> sizes = parameters.getSupportedPreviewSizes();
        Size optimalSize = getOptimalPreviewSize(sizes, width, height);         
        Log.d(TAG, "Surface size is " + width + "w " + height + "h");
        Log.d(TAG, "Optimal size is " + optimalSize.width + "w " + optimalSize.height + "h");           
        parameters.setPreviewSize(optimalSize.width, optimalSize.height);           
        // parameters.setPreviewSize(width, height);            
        camera.setParameters(parameters);
        camera.startPreview();
    }
};  

6
AFAIK ক্যামেরার পূর্বরূপটি কেবলমাত্র আড়াআড়িভাবে কাজ করে, কমপক্ষে 2.2 এবং তারও আগের জন্য। আমি অনুমান করি যে, ক্যামেরা প্রিভিউ করে এমন ক্রিয়াকলাপগুলি সিস্টেম নোটিফিকেশন বারটি লুকিয়ে রাখে এবং শিরোনামগুলি রাখে না ... দৃশ্যত প্রতিকৃতি সত্ত্বেও আমি মনে করি তারা "সত্যই" ল্যান্ডস্কেপ।
রূবেন স্ক্র্যাটন

উত্তর:


71

অন্য সদস্য এবং আমার সমস্যা থেকে:

ক্যামেরা রোটেশন ইস্যু বিভিন্ন ডিভাইস এবং নির্দিষ্ট সংস্করণের উপর নির্ভর করে।

সংস্করণ 1.6: ঘূর্ণন সমস্যাটি স্থির করতে এবং এটি বেশিরভাগ ডিভাইসের জন্যই ভাল

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
        {   
            p.set("orientation", "portrait");
            p.set("rotation",90);
        }
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
        {                               
            p.set("orientation", "landscape");          
            p.set("rotation", 90);
        }

সংস্করণ ২.১: ধরণের ডিভাইসের উপর নির্ভর করে, উদাহরণস্বরূপ, এক্সপিরিয়া এক্স 10 দিয়ে সমস্যাটি সমাধান করা যায় না, তবে এটি এক্স 8, এবং মিনির পক্ষে ভাল

Camera.Parameters parameters = camera.getParameters();
parameters.set("orientation", "portrait");
camera.setParameters(parameters);

সংস্করণ ২.২: সমস্ত ডিভাইসের জন্য নয়

camera.setDisplayOrientation(90);

http://code.google.com/p/android/issues/detail?id=1193#c42


4
এখানে সংস্করণ বলতে কী বোঝ?
মোঃ সুলায়মান

31

জাভাডোকস থেকে setDisplayOrientation(int)(এপিআই স্তর 9 প্রয়োজন):

 public static void setCameraDisplayOrientation(Activity activity,
         int cameraId, android.hardware.Camera camera) {
     android.hardware.Camera.CameraInfo info =
             new android.hardware.Camera.CameraInfo();
     android.hardware.Camera.getCameraInfo(cameraId, info);
     int rotation = activity.getWindowManager().getDefaultDisplay()
             .getRotation();
     int degrees = 0;
     switch (rotation) {
         case Surface.ROTATION_0: degrees = 0; break;
         case Surface.ROTATION_90: degrees = 90; break;
         case Surface.ROTATION_180: degrees = 180; break;
         case Surface.ROTATION_270: degrees = 270; break;
     }

     int result;
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
         result = (info.orientation + degrees) % 360;
         result = (360 - result) % 360;  // compensate the mirror
     } else {  // back-facing
         result = (info.orientation - degrees + 360) % 360;
     }
     camera.setDisplayOrientation(result);
 }

4
@ ডেরজু ক্লাসটি CameraInfoএপিআই লেভেল 9 পর্যন্ত চালু করা হয়নি, সুতরাং আমি যে পদ্ধতিটি পোস্ট করেছি তার জন্য এপিআই স্তর 9 প্রয়োজন।
জেসন রবিনসন

4
result = (360 - result) % 360; // compensate the mirrorমুছে ফেলা উচিত , সামনের ক্যামেরা থেকে ছবি অন্যথায় ভুলভাবে আবর্তিত হবে
stevo.mit

@ stevo.mit আপনি একাধিক ডিভাইসে এটি যাচাই করেছেন? আমি এই কোডটি বেশ কয়েকবার ঘোরানোর জন্য ব্যবহার করেছি এবং কোনও ভুল ঘূর্ণনের মুখোমুখি হইনি।
জেসন রবিনসন

4
@ জেসন রবিনসন আমার কয়েকটি মডেলের তালিকা রয়েছে যার উপর এপিআই স্তর 9 এর উপরে রয়েছে তবে এখনও এই পদ্ধতির কোনও প্রভাব নেই। এটির হার্ডওয়্যার সম্পর্কিত সমস্যা আবহাওয়া সম্পর্কে জানেন না। ডিভাইসের তালিকা ঘূর্ণন_বিধি_মোডেলস = অ্যারে.এএসলিস্ট ("জিটি-এস5360", "জিটি-এস6802", "জিটি-এস5830 সি", "জিটি-এস5830 আই", "ড্রোড 2", "গ্লোবাল", "এক্সটি 557", "ডিজায়ার এইচডি", " PC36100 "," GT-I9000 "," ADR6350 "," Mi-One Plus "," SGH-T989 "," GT-I9100 "," GT-I9001 ");
বিক্রম

4
@ আবদুল মোহসিন বিকাশকারী.অ্যান্ড্রয়েড / রেফারেন্স / অ্যান্ড্রয়েড / শারওয়ার / দেখুন দেখুন , বিশেষত ক্যামেরা_ফ্যাকিং_ব্যাক এবং ক্যামেরা_ফ্যাকিং_এফআরএনটি।
জেসন রবিনসন

25

এই সমাধানটি অ্যান্ড্রয়েডের সমস্ত সংস্করণের জন্য কাজ করবে । আপনি সমস্ত অ্যান্ড্রয়েড ডিভাইসের জন্য এটি কাজ করতে জাভাতে প্রতিবিম্ব ব্যবহার করতে পারেন:

মূলত আপনার নির্দিষ্ট পদ্ধতিটি কল করার পরিবর্তে অ্যান্ড্রয়েড ২.২ সেটডিসপ্লে ওরিয়েন্টেশন কল করতে একটি প্রতিবিম্ব র‌্যাপার তৈরি করা উচিত।

পদ্ধতি:

    protected void setDisplayOrientation(Camera camera, int angle){
    Method downPolymorphic;
    try
    {
        downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
        if (downPolymorphic != null)
            downPolymorphic.invoke(camera, new Object[] { angle });
    }
    catch (Exception e1)
    {
    }
}

এবং ক্যামেরা.সেট ডিসপ্লে ওরিয়েন্টেশন (এক্স) ব্যবহারের পরিবর্তে সেটডিসপ্লে ওরিয়েন্টেশন (ক্যামেরা, এক্স) ব্যবহার করুন :

    if (Integer.parseInt(Build.VERSION.SDK) >= 8)
        setDisplayOrientation(mCamera, 90);
    else
    {
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
        {
            p.set("orientation", "portrait");
            p.set("rotation", 90);
        }
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
        {
            p.set("orientation", "landscape");
            p.set("rotation", 90);
        }
    }   

4
অন্য অংশটি কিছু 2.1 ডিভাইসে কাজ করে তবে সমস্ত নয় (উপরে মেডেনেকের ব্যাখ্যা দেখুন)।
এরিক চেন

4
আমি মনে করি পি টাইপের হয় Camera.Parameters। নিম্নলিখিত লাইনটি যুক্ত করার চেষ্টা করুন:Camera.Parameters p = camera.getParameters();
সেহরিশ খান

6

আমি যখন ট্যাবগুলিতে স্ক্যান করার জন্য জেডবার ব্যবহার করছিলাম তখন আমি সমস্যার মুখোমুখি হয়েছি। ক্যামেরা ওরিয়েন্টেশন সমস্যা। নীচে কোড ব্যবহার করে আমি সমস্যার সমাধান করতে সক্ষম হয়েছি। এটি পুরো কোড স্নিপেট নয়, দয়া করে এ থেকে কেবল সহায়তা নিন।

 public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
     if (isPreviewRunning) {
            mCamera.stopPreview();
        }

 setCameraDisplayOrientation(mCamera);

        previewCamera();

    }



 public void previewCamera() {

        try {
            // Hard code camera surface rotation 90 degs to match Activity view
            // in portrait
            mCamera.setPreviewDisplay(mHolder);
            mCamera.setPreviewCallback(previewCallback);
            mCamera.startPreview();
            mCamera.autoFocus(autoFocusCallback);
            isPreviewRunning = true;
        } catch (Exception e) {
            Log.d("DBG", "Error starting camera preview: " + e.getMessage());
        }


    }


public void setCameraDisplayOrientation(android.hardware.Camera camera) {
        Camera.Parameters parameters = camera.getParameters();

        android.hardware.Camera.CameraInfo camInfo =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(getBackFacingCameraId(), camInfo);


        Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        int rotation = display.getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (camInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (camInfo.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (camInfo.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }




    private int getBackFacingCameraId() {
        int cameraId = -1;
        // Search for the front facing camera
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {

                cameraId = i;
                break;
            }
        }
        return cameraId;
    }

5

আমি অবশেষে গুগলের ক্যামেরা অ্যাপ্লিকেশনটি ব্যবহার করে এটি ঠিক করেছি। এটি সেন্সর ব্যবহার করে ফোনের ওরিয়েন্টেশন পায় এবং তারপরে যথাযথভাবে এক্সআইএফ ট্যাগটি সেট করে। জেপিইজি যা ক্যামেরা থেকে বেরিয়ে আসে তা স্বয়ংক্রিয়ভাবে ওরিয়েন্টেড হয় না।

এছাড়াও, ক্যামেরা প্রিভিউটি কেবলমাত্র ল্যান্ডস্কেপ মোডে সঠিকভাবে কাজ করে। আপনার যদি প্রতিক্রিয়ার দিকে মনোযোগ দেওয়ার জন্য আপনার ক্রিয়াকলাপের বিন্যাস প্রয়োজন হয় তবে আপনাকে এটি ওরিয়েন্টেশন সেন্সরটির মানটি ব্যবহার করে ম্যানুয়ালি করতে হবে।


4
ওহে, ওরিয়েন্টেশন সেন্সর ব্যবহার করে ক্যামেরা ওরিয়েন্টেশন কীভাবে পাবেন ?? দয়া করে আপনার কোডটি ভাগ করুন ...
ish

@Rishi এই লিঙ্কটি দেখতে stackoverflow.com/questions/9055460/...
PiyushMishra

4
সহায়তার জন্য ধন্যবাদ, তবে আমার সমস্যাটি হ'ল আমি যখন পোর্ট্রেট মোডে সিমসং ফোনে ছবি তুলি তখন আমার স্ক্রিনে 90 ডিগ্রি ঘোরানো ফটো প্রদর্শিত হয়। সুতরাং, আমি ক্যামেরার অভিমুখীকরণের চেষ্টা করছি, তাই আমি পোট্রেট মোডের জন্য 90 ডিগ্রি ফটো ঘোরান
ish

5

এই সমাধানটি পরীক্ষা করে দেখুন

 public static void setCameraDisplayOrientation(Activity activity,
                                                   int cameraId, android.hardware.Camera camera) {
        android.hardware.Camera.CameraInfo info =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0: degrees = 0; break;
            case Surface.ROTATION_90: degrees = 90; break;
            case Surface.ROTATION_180: degrees = 180; break;
            case Surface.ROTATION_270: degrees = 270; break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }

সামনের সামনের ক্যামেরাটি পরিচালনা করার জন্য ধন্যবাদ। এটি আমার সমস্যার সমাধান করেছে
লুই সিএডি

আপনার সমাধানটি লুইসক্যাডকে দেখে খুশি যে আমার সমাধানটি আপনার সমস্যার সমাধান করে।
মুদাসসির খান

4

এই সমস্যাটি অনেক দিন আগেই সমাধান করা হয়েছিল তবে আমি সমস্ত টুকরো টুকরো টুকরো টুকরো টুকরো করে রাখার জন্য কিছু সমস্যার মুখোমুখি হয়েছিলাম তাই এখানেই আমার চূড়ান্ত সমাধান, আমি আশা করি এটি অন্যকে সহায়তা করবে:

public void startPreview() {
        try {
            Log.i(TAG, "starting preview: " + started);

            // ....
            Camera.CameraInfo camInfo = new Camera.CameraInfo();
            Camera.getCameraInfo(cameraIndex, camInfo);
            int cameraRotationOffset = camInfo.orientation;
            // ...

            Camera.Parameters parameters = camera.getParameters();
            List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
            Camera.Size previewSize = null;
            float closestRatio = Float.MAX_VALUE;

            int targetPreviewWidth = isLandscape() ? getWidth() : getHeight();
            int targetPreviewHeight = isLandscape() ? getHeight() : getWidth();
            float targetRatio = targetPreviewWidth / (float) targetPreviewHeight;

            Log.v(TAG, "target size: " + targetPreviewWidth + " / " + targetPreviewHeight + " ratio:" + targetRatio);
            for (Camera.Size candidateSize : previewSizes) {
                float whRatio = candidateSize.width / (float) candidateSize.height;
                if (previewSize == null || Math.abs(targetRatio - whRatio) < Math.abs(targetRatio - closestRatio)) {
                    closestRatio = whRatio;
                    previewSize = candidateSize;
                }
            }

            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            int degrees = 0;
            switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break; // Natural orientation
            case Surface.ROTATION_90:
                degrees = 90;
                break; // Landscape left
            case Surface.ROTATION_180:
                degrees = 180;
                break;// Upside down
            case Surface.ROTATION_270:
                degrees = 270;
                break;// Landscape right
            }
            int displayRotation;
            if (isFrontFacingCam) {
                displayRotation = (cameraRotationOffset + degrees) % 360;
                displayRotation = (360 - displayRotation) % 360; // compensate
                                                                    // the
                                                                    // mirror
            } else { // back-facing
                displayRotation = (cameraRotationOffset - degrees + 360) % 360;
            }

            Log.v(TAG, "rotation cam / phone = displayRotation: " + cameraRotationOffset + " / " + degrees + " = "
                    + displayRotation);

            this.camera.setDisplayOrientation(displayRotation);

            int rotate;
            if (isFrontFacingCam) {
                rotate = (360 + cameraRotationOffset + degrees) % 360;
            } else {
                rotate = (360 + cameraRotationOffset - degrees) % 360;
            }

            Log.v(TAG, "screenshot rotation: " + cameraRotationOffset + " / " + degrees + " = " + rotate);

            Log.v(TAG, "preview size: " + previewSize.width + " / " + previewSize.height);
            parameters.setPreviewSize(previewSize.width, previewSize.height);
            parameters.setRotation(rotate);
            camera.setParameters(parameters);
            camera.setPreviewDisplay(mHolder);
            camera.startPreview();

            Log.d(TAG, "preview started");

            started = true;
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

'আমি আশা করি এটি অন্যকে সহায়তা করবে' না, তা হবে না। আপনার কোডের অংশটি প্রসঙ্গের বাইরে টানা হয়েছে। উদাহরণস্বরূপ, 'ইসফ্রন্টফ্যাকিংক্যাম' কোথা থেকে আসছে?
seanpj

4
আমি মনে করি এটি আসলে অন্য একটি বিষয়, প্রাথমিক সমস্যার তুলনায় এটি আসলে কিছুই নয়। আপনি এটিকে android.hardware.Camera.CameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT থেকে পেতে পারেন। এই সম্পর্কে দুঃখিত।
লুই গ্রেগনন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.