Bitmap nach kilobyte komprimieren

  • Antworten:5
Benjamin F.
  • Forum-Beiträge: 4

10.08.2017, 11:34:26 via Website

Hallo leute,

Ums kurz zu machen:
Ich habe eine Fileserver auf dem ich JPEG Speichere. Diese sollen über die Application auf 50 Kb komprimiert werden. So sieht mein code bis hierhin aus um die Bitmap-größe zu bekommen:

                ByteArrayOutputStream baos = new ByteArrayOutputStream();

                Bitmap originBitmap = BitmapFactory.decodeFile(filepath);
                originBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                byte[] imageInByte = baos.toByteArray();
                long lengthbmp = imageInByte.length / 1000; //dividing with 1000 is Kilobytes
                Toast.makeText(getContext(), String.valueOf(lengthbmp) + " kb", 
                                                                            Toast.LENGTH_SHORT).show();

Ich weiß jedoch nicht ob das so überhaupt sinnvoll ist und wie ich weitermachen soll um das ganze über eine schleife weiter zu komprimieren auf 50 Kb.

Antworten
swa00
  • Forum-Beiträge: 3.704

10.08.2017, 17:38:36 via Website

Hallo Benjamin ,

und was spricht dagegen, den Kompressionsfaktor direkt anzuwenden ??

— geändert am 10.08.2017, 17:44:41

Liebe Grüße - Stefan
[ App - Entwicklung ]

Antworten
Benjamin F.
  • Forum-Beiträge: 4

11.08.2017, 11:41:13 via Website

Ich hatte es probiert doch ein paar problemchen. Nun hab ich eine halbwegs funktionierende Methode.
Jedoch ist manchmal die Qualität zu schlecht. Vielleicht hat jemand eine Idee wo man da noch ansetzen kann?
Natürlich kann ich die Kilobyte grenze erhöhen. Diese sollte jedoch wie gesagt möglichst klein sein.

Hier mal der neue Code:

public static Bitmap compressBitmap(Context ctx, Bitmap bmp){
    Bitmap editBmp = bmp;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    try {
        //Change Bmp x- or y-size smaller than 1000
        while(editBmp.getWidth() > 1000 || editBmp.getHeight() > 1000){
            editBmp = Bitmap.createScaledBitmap(editBmp, editBmp.getWidth()/2, editBmp.getHeight()/2, false);
        }

        //read bitmap bytesize
        editBmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] imageInByte = baos.toByteArray();
        long lengthbmp = imageInByte.length / 1000; //dividing with 1000 is Kilobytes

        bmp = editBmp;
        int quality = 100;

        //reduce bmp bytesize to 50 Kb with quality reduction
        while(lengthbmp >= 50) {
            if(quality <= 0){
                break;
            }
            baos = new ByteArrayOutputStream();
            editBmp = bmp;
            quality -= 5;
            editBmp.compress(Bitmap.CompressFormat.JPEG, quality, baos);
            imageInByte = baos.toByteArray();
            lengthbmp = imageInByte.length / 1000; //dividing with 1000 is Kilobytes
        }

        return editBmp;

    } catch (Exception e) {
        return null;
    }
}

Antworten
swa00
  • Forum-Beiträge: 3.704

11.08.2017, 11:52:29 via Website

Hallo Benjamin,

EDIT :

Es ist völlig normal , dass dein Bild unscharf wird ..
Innerhalb der Kompression wird durch den Faktor dein RunLength der Zeile verändert.
(Benachbarte "ähnliche" Pixel werden zusammengeführt)

Abhilfe schafft dir dazu nur eine andere verlustfreie(re) Kompression e.g. jpeg2000

Muss denn die Dimensions beibehalten werden ??

— geändert am 11.08.2017, 12:04:43

Liebe Grüße - Stefan
[ App - Entwicklung ]

Antworten
Benjamin F.
  • Forum-Beiträge: 4

11.08.2017, 12:24:47 via Website

Wie die Kompression dahinter funktioniert ist mir bewusst. Die Verständnis grenze liegt hier eher bei, wie setze ich es programmiertechnisch um. Wie kann ich denn das ganze auf jpeg2000 konvertieren?

Die Dimension sollte nur im Verhältnis zum original bleiben. Ansonsten kann sie variabel sein, solange man sie noch erkennt auf einem Smartphone.

Antworten
swa00
  • Forum-Beiträge: 3.704

11.08.2017, 12:34:06 via Website

Wie die Kompression dahinter funktioniert ist mir bewusst

Da du dich allerdings über die Qualität "beschwert" hattest und Dein erster Versuch ein wenig "unbeholfen" war,
konnte man nicht davon ausgehen :-)

a) JPG2000 : Es gibt jede menge Libraries dazu.
b) Und warum machst du dir dann keine Thumbnails ?

Grundsätzlich gilt :
Für die Reduzierung eines Images auf den Speicherplatz bezogen , bleibt dir nur bei JPEG ein anderer Kompressionsfaktor,
ein anderer Kompressionalgorythmus, oder die Reduktion der Dimensions.

Dein erster Versuch musste also unweigerlich scheitern .

— geändert am 11.08.2017, 13:44:02

Liebe Grüße - Stefan
[ App - Entwicklung ]

Antworten