Foto mit einer bestimmten Auflösung aufnehmen und als Datei ablegen.

insidERR

Mitglied
Hallo zusammen.
Ich bastle gerade an einer einfachen App, welche nur ein View mit einem Vorschuafenster und den Buttons: "Foto aufnehmen", "Foto uploaden" und Reset hat.
Es funktioniert auch alles soweit. Nur soll die App nicht die volle Sensorauflösung benutzen, da man auf den Fotos nicht jedes Krümmel in 10m Entfernung erkennen soll. Die Datenmenge wird einfach zu groß.
6-7MB sind mir zu viel. Auf einem anderen Gerät entstehen Foto mit max.2MB. Das reicht völlig.

Hier der Code, der durch den Button "Foto aufnehmen" aufgerufen wird.
Java:
    private void capturePhoto(String tmpFileName) {
        long timestamp = System.currentTimeMillis();
        ContentValues contentValues = new ContentValues();
        tmpFileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ "/" + tmpFileName +".jpg";

        contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, "Archivator");
        contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);

        contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
        contentValues.put(MediaStore.MediaColumns.HEIGHT,2592);  //diese Zeile wird ignoriert
        contentValues.put(MediaStore.MediaColumns.WIDTH,1944);   //diese Zeile wird ignoriert

        imgFileName=tmpFileName;
        String finalTmpFileName = tmpFileName;
        imageCapture.takePicture(new ImageCapture.OutputFileOptions.Builder(getContentResolver(),MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues).build(), getExecutor(),new ImageCapture.OnImageSavedCallback()
                {
                    @Override
                    public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                        File imgFile = new  File(finalTmpFileName);
                        Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
                        ImageView myImage = (ImageView) previewImage;
                        myImage.setImageBitmap(myBitmap);
                    }

                    @Override
                    public void onError(@NonNull ImageCaptureException exception) {
                        System.out.println("Zeile: ERR " + exception.getMessage());
                        Toast.makeText(MainActivity.this, "Fehler: " + exception.getMessage() , Toast.LENGTH_SHORT).show();
                    }
                }
        );
    }

Ich habe zwei Zeilen markiert, die anscheinend ignoriert werden, da die Fotos eine Auflösung von 3456x4608 haben.
Hat jemand ne Idee, woran es liegt und was geändert werden kann/soll, damit es funktioniert?

Danke
 
Ein Ansatz wäre erst einmal, dass man dies im Builder von ImageCapture angibt per setTargetResolution:

Aber die Dokumentation gibt auch eine klare Aussage, dass immer die nächste mögliche Auflösung genommen wird. Da sind also nicht beliebige Dinge wählbar. Wenn die Kamera da also etwas nicht unterstützt, dann wird das ignoriert. Daher kann Dein Weg auch prinzipiell funktionieren nur eben mit den gleichen Einschränkungen.

Daher evtl. einfach erst einmal schauen, was für Auflösungen überhaupt unterstützt werden um da dann eine vorhandene zu wählen.
 
Hallo dann setze doch gleich die Camera2 Eigenschaften auf die Gösse wie du sie haben willst.
Also mach das Foto schon in der richtigen Größe.
 
Hallo ihr beiden,
danke für die Ideen. Haben haben mich zum Ergebnis geführt.

Hätte vielleicht noch den Code für die Vorschau mit angeben sollen. Dort konnte man wirklich die Auflösung einstellen. Die Kamera schluckt nicht alles, so musste ich erst mit einer anderen App herausfinden, was geht.

Java:
   private void startCameraX(ProcessCameraProvider cameraProvider) {
        cameraProvider.unbindAll();
        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build();
        Preview preview = new Preview.Builder()
                .setMaxResolution(new Size(500,750))
                .build();
        preview.setSurfaceProvider(previewView.getSurfaceProvider());


        //Auflösungen des Xcover 5
        //1440x1080 ;

        // Image capture use case
        imageCapture = new ImageCapture.Builder()
                //.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
                //.setSoftwareJpegEncoderRequested(true)
                .setTargetResolution(new Size(1080,1440))
                //.setTargetRotation(Surface.ROTATION_0)
                //.setTargetAspectRatio(AspectRatio.RATIO_4_3)
                .build();


        //bind to lifecycle:
        cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);
    }
 
Auch wenn meine Antwort etwas spät ist aber wenn du nur zum Testen die Auflösung hardcoded einträgst bzw. du nur auf einem Handy das ganze entwickeltest ist das I.O.. Besser wäre es natürlich, die Auflösung von der cameraX API zur Laufzeit zu übergeben.

Zusätzlich, ich habe mehr oder weniger Erfahrung mit der Camera API und der Camera2 API. Letzteres ist eine Lowlevel API, die mich Nächte gekostet hat, gerade dann wenn du Nischen-Handys verwendest. Aber CameraX API von Google baut auf die camera2 API auf ist aber im Vergleich zu diesem Framework zum Teil immer noch sehr umfangreich.

Wenn du was schnelles suchst, kann ich dir nur dieses Framework empfehlen.
 
Hi @DefconDev
Danke für deinen Post.

Ich hatte diese App "CameraView" schon gesehen und auch ausprobiert. Habe mir damit die möglichen Auflösungen anzeigen lassen und mich für die kleinste entschieden. Habe außerdem noch einen "Qualitätsmodus" in der App, wo die maximale Auflösung genommen wird. Allerdings werden die Fotos dann >10MB groß.

Die App soll auf nur zwei verschiedenen Geräten laufen.
Wir nutzen in der Firma in der Versandabteilung eine spezielle(nicht günstige) Kamera (G700SE mit Barcodescanner) von wo die Fotos 1x/Woche herunterladen und passend wegsortiert werden. Diese soll jetzt durch ein Smartphone (Xcover 5) mit meiner App ersetzt werden. Machen im Prinzip das gleiche. Nur das Smartphone ist günstiger und flexibler.

In ner anderen Abteilung wird eine ältere IXUS benutzt. Da ist es lästig die Fotos auf den PC zu laden. Mit der aktuellen Lösung wird das Foto bereits beim Erstellen auf den Server geladen wodurch das "SD-Karte raus, in der Leser rein und übertragen" entfällt. Kollegen, die das jetzt nutzen, sind begeistert.
 

Zurück
Oben