Convert bitmap to base64 string in blackberry

后端 未结 3 1191
没有蜡笔的小新
没有蜡笔的小新 2021-01-29 08:25

I have an image which needs to be sent to the server. Is there a way to convert a bitmap(jpg) to base64 string in blackberry?

相关标签:
3条回答
  • 2021-01-29 08:53

    Found this one, much faster conversion of Bitmap to byte[]. Exactly what I needed.

    import java.io.*;
    import javax.microedition.lcdui.Image;
    import net.rim.device.api.compress.ZLibOutputStream;
    
    public class MinimalPNGEncoder
    {
      public static Image toImage(int width, int height, byte[] alpha, byte[] red, byte[] green, byte[] blue)
    {
        try    
        {
        byte[] png = toPNG(width, height, alpha, red, green, blue);
        return Image.createImage(png, 0, png.length);
        }
        catch (IOException e)
        {
        return null;
        }
    }
    
    public static byte[] toPNG(int width, int height, byte[] alpha, byte[] red, byte[] green, byte[] blue) throws IOException
     {
        byte[] signature = new byte[] {(byte) 137, (byte) 80, (byte) 78, (byte) 71, (byte) 13, (byte) 10, (byte) 26, (byte) 10};
        byte[] header = createHeaderChunk(width, height);
        byte[] data = createDataChunk(width, height, alpha, red, green, blue);
        byte[] trailer = createTrailerChunk();
    
        ByteArrayOutputStream png = new ByteArrayOutputStream(signature.length + header.length + data.length + trailer.length);
        png.write(signature);
        png.write(header);
        png.write(data);
        png.write(trailer);
        return png.toByteArray();
     }
    
    public static byte[] createHeaderChunk(int width, int height) throws IOException
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(13);
        DataOutputStream chunk = new DataOutputStream(baos);
        chunk.writeInt(width);
        chunk.writeInt(height);
        chunk.writeByte(8); // Bitdepth
        chunk.writeByte(6); // Colortype ARGB
        chunk.writeByte(0); // Compression
        chunk.writeByte(0); // Filter
        chunk.writeByte(0); // Interlace    
        return toChunk("IHDR", baos.toByteArray());
    }
    
    public static byte[] createDataChunk(int width, int height, byte[] alpha, byte[] red, byte[] green, byte[] blue) throws IOException
    {    
        int source = 0;
        int dest = 0;
        byte[] raw = new byte[4*(width*height) + height];
        for (int y = 0; y < height; y++)
        {
          raw[dest++] = 0; // No filter
          for (int x = 0; x < width; x++)
          {
            raw[dest++] = red[source];
            raw[dest++] = green[source];
            raw[dest++] = blue[source];
            raw[dest++] = alpha[source++];
          }
        }
        return toChunk("IDAT", toZLIB(raw));
    }
    
    public static byte[] createTrailerChunk() throws IOException
    {
        return toChunk("IEND", new byte[] {});
    }
    
    public static byte[] toChunk(String id, byte[] raw) throws IOException
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(raw.length + 12);
        DataOutputStream chunk = new DataOutputStream(baos);
    
        chunk.writeInt(raw.length);
    
        byte[] bid = new byte[4];
        for (int i = 0; i < 4; i++)
        {
            bid[i] = (byte) id.charAt(i);
        }
    
        chunk.write(bid);
    
        chunk.write(raw);
    
        int crc = 0xFFFFFFFF;
        crc = updateCRC(crc, bid);  
        crc = updateCRC(crc, raw);    
        chunk.writeInt(~crc);
    
        return baos.toByteArray();
    }
    
    static int[] crcTable = null;
    
    public static void createCRCTable()
    {
        crcTable = new int[256];
    
        for (int i = 0; i < 256; i++)
        {
          int c = i;
          for (int k = 0; k < 8; k++)
          {
            c = ((c & 1) > 0) ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
          }
          crcTable[i] = c;
        }
    }
    
    public static int updateCRC(int crc, byte[] raw)
    {
        if (crcTable == null)
        {
          createCRCTable();
        }
    
        for (int i = 0; i < raw.length; i++)
        {
          crc = crcTable[(crc ^ raw[i]) & 0xFF] ^ (crc >>> 8);      
        }
    
        return crc;
    }
    
    /* This method is called to encode the image data as a zlib
     block as required by the PNG specification. This file comes
     with a minimal ZLIB encoder which uses uncompressed deflate
     blocks (fast, short, easy, but no compression). If you want
     compression, call another encoder (such as JZLib?) here. */
    public static byte[] toZLIB(byte[] raw) throws IOException
    {
          //used the BB ZLib ...
      ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024);
      ZLibOutputStream compBytes = new ZLibOutputStream(outBytes, false, 10, 9);
      compBytes.write(raw, 0, raw.length);
      compBytes.close();
      return outBytes.toByteArray();
     //return ZLIB.toZLIB(raw);
     }
    }
    
    
    
    class ZLIB
    {
      static final int BLOCK_SIZE = 32000;
    
      public static byte[] toZLIB(byte[] raw) throws IOException
    {    
        ByteArrayOutputStream baos = new ByteArrayOutputStream(raw.length + 6 + (raw.length / BLOCK_SIZE) * 5);
        DataOutputStream zlib = new DataOutputStream(baos);
    
        byte tmp = (byte) 8;       
        zlib.writeByte(tmp);                           // CM = 8, CMINFO = 0
        zlib.writeByte((31 - ((tmp << 8) % 31)) % 31); // FCHECK (FDICT/FLEVEL=0)
    
        int pos = 0;
        while (raw.length - pos > BLOCK_SIZE)
        {
          writeUncompressedDeflateBlock(zlib, false, raw, pos, (char) BLOCK_SIZE);
          pos += BLOCK_SIZE;
        }
    
        writeUncompressedDeflateBlock(zlib, true, raw, pos, (char) (raw.length - pos));
    
        // zlib check sum of uncompressed data
        zlib.writeInt(calcADLER32(raw));
    
        return baos.toByteArray();
     }
    
     private static void writeUncompressedDeflateBlock(DataOutputStream zlib, boolean last,
                        byte[] raw, int off, char len) throws IOException
     {
        zlib.writeByte((byte)(last ? 1 : 0));         // Final flag, Compression type 0
        zlib.writeByte((byte)(len & 0xFF));           // Length LSB
        zlib.writeByte((byte)((len & 0xFF00) >> 8));  // Length MSB
        zlib.writeByte((byte)(~len & 0xFF));          // Length 1st complement LSB
        zlib.writeByte((byte)((~len & 0xFF00) >> 8)); // Length 1st complement MSB 
        zlib.write(raw,off,len);                      // Data    
     }
    
     private static int calcADLER32(byte[] raw)
     {
        int s1 = 1;
        int s2 = 0;
        for (int i = 0; i < raw.length; i++)
        {
          int abs = raw[i] >=0 ? raw[i] : (raw[i] + 256);
          s1 = (s1 + abs) % 65521;
          s2 = (s2 + s1) % 65521;      
        }
        return (s2 << 16) + s1;
     }
    }
    

    And this is the method that you need to invoke.

    public static byte[] toPNG(Bitmap image) throws IOException {
    
        int imageSize = image.getWidth() * image.getHeight();
        int[] rgbs = new int[imageSize];
        byte[] a, r, g, b;
        int colorToDecode;
    
        image.getARGB(rgbs, 0, image.getWidth() , 0, 0, image.getWidth(), image.getHeight());
    
        a = new byte[imageSize];
        r = new byte[imageSize];
        g = new byte[imageSize];
        b = new byte[imageSize];
    
        for (int i = 0; i < imageSize; i++) {
            colorToDecode = rgbs[i];
    
            a[i] = (byte) ((colorToDecode & 0xFF000000) >>> 24);
            r[i] = (byte) ((colorToDecode & 0x00FF0000) >>> 16);
            g[i] = (byte) ((colorToDecode & 0x0000FF00) >>> 8);
            b[i] = (byte) ((colorToDecode & 0x000000FF));
        }
    
        return MinimalPNGEncoder.toPNG(image.getWidth(), image.getHeight(), a, r, g, b);
    } 
    

    This is not mine. I am so grateful to Christian Fr�schlin for creating this and letting other developers to use this. This is the link for the terms.

    Before i forgot, this one has a limitation. It can converts successfully a bitmap to byte[] which size is less than or equal to 63kb, but if the size exceeds the limit the converted image will be discolored.

    0 讨论(0)
  • 2021-01-29 09:02
    package com.covidien.screens;
    
    import java.io.OutputStream;
    
    import javax.microedition.io.Connector;
    import javax.microedition.io.file.FileConnection;
    
    import net.rim.device.api.system.Bitmap;
    import net.rim.device.api.system.CDMAInfo;
    import net.rim.device.api.system.GPRSInfo;
    import net.rim.device.api.system.IDENInfo;
    import net.rim.device.api.system.RadioInfo;
    import net.rim.device.api.ui.Field;
    import net.rim.device.api.ui.FieldChangeListener;
    import net.rim.device.api.ui.UiApplication;
    import net.rim.device.api.ui.component.BitmapField;
    import net.rim.device.api.ui.component.ButtonField;
    import net.rim.device.api.ui.component.Dialog;
    import net.rim.device.api.ui.container.HorizontalFieldManager;
    import net.rim.device.api.ui.container.MainScreen;
    
    import org.kobjects.base64.Base64;
    import org.ksoap2.SoapEnvelope;
    import org.ksoap2.serialization.SoapObject;
    import org.ksoap2.serialization.SoapSerializationEnvelope;
    import org.ksoap2.transport.HttpTransport;
    
    
    public final class ImageScreen extends MainScreen
    {
        /** The down-scaling ratio applied to the snapshot Bitmap */
        private static final int IMAGE_SCALING = 5;
        private static final String boundary = "31BF3856AD364E35";
        /** The base file name used to store pictures */
        private static String FILE_NAME = System.getProperty("fileconn.dir.photos") + "IMAGE";
    
        /** The extension of the pictures to be saved */
        private static String EXTENSION = ".png";
    
        /** A counter for the number of snapshots taken */
        private static int _counter;
    
        /** A reference to the current screen for listeners */
        private ImageScreen _imageScreen;
    
        static String imageName=null;
        /**
        * Constructor
        * @param raw A byte array representing an image
        */
        public ImageScreen( final byte[] raw )
        {
            // A reference to this object, to be used in listeners
            _imageScreen = this;
    
            setTitle("IMAGE");
    
            // Convert the byte array to a Bitmap image
            Bitmap image = Bitmap.createBitmapFromBytes( raw, 0, -1, IMAGE_SCALING );
    
            // Create two field managers to center the screen's contents
            HorizontalFieldManager hfm1 = new HorizontalFieldManager( Field.FIELD_HCENTER );
            HorizontalFieldManager hfm2 = new HorizontalFieldManager( Field.FIELD_HCENTER );
    
            // Create the field that contains the image
            BitmapField imageField = new BitmapField( image );
            hfm1.add( imageField );
    
            // Create the SAVE button which returns the user to the main camera
            // screen and saves the picture as a file.
            ButtonField photoButton = new ButtonField( "Use" );
            photoButton.setChangeListener( new SaveListener(raw) );
            hfm2.add(photoButton);
    
            // Create the CANCEL button which returns the user to the main camera
            // screen without saving the picture.
            ButtonField cancelButton = new ButtonField( "Retake" );
            cancelButton.setChangeListener( new CancelListener() );
            hfm2.add(cancelButton);
    
            // Add the field managers to the screen
            add( hfm1 );
            add( hfm2 );
        }
    
        /**
        * Handles trackball click events
        * @see net.rim.device.api.ui.Screen#invokeAction(int)
        */
        protected boolean invokeAction(int action)
        {
            boolean handled = super.invokeAction(action);
    
            if(!handled)
            {
                switch(action)
                {
                    case ACTION_INVOKE: // Trackball click.
                    {
                        return true;
                    }
                }
            }
            return handled;
        }
    
        /**
        * A listener used for the "Save" button
        */
        private class SaveListener implements FieldChangeListener
        {
    
    
            /** A byte array representing an image */
            private byte[] _raw;
    
            /**
            * Constructor.
            * @param raw A byte array representing an image
            */
            SaveListener(byte[] raw)
            {
                _raw = raw;
            }
    
            /**
            * Saves the image as a file in the BlackBerry filesystem
            */
            public void fieldChanged(Field field, int context)
            {
                try
                {
                    // Create the connection to a file that may or
                    // may not exist.
                    FileConnection file = (FileConnection)Connector.open( FILE_NAME + _counter + EXTENSION );
    
                    // If the file exists, increment the counter until we find
                    // one that hasn't been created yet.
                    while( file.exists() )
                    {
                        file.close();
                        ++_counter;
                        file = (FileConnection)Connector.open( FILE_NAME + _counter + EXTENSION );
                    }
    
                    // We know the file doesn't exist yet, so create it
                    file.create();
    
                    // Write the image to the file
                    OutputStream out = file.openOutputStream();
                    out.write(_raw);
    
                    System.out.println("Boundary  :::::"+boundary);
                    //*******************************************************************************************************
                    String serviceUrl = "URL/Service.asmx";
                    String serviceNamespace = "http://tempuri.org/";
                    String soapAction="http://tempuri.org/Upload";
                    SoapObject rpc = new SoapObject(serviceNamespace, "Upload");
                    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    
                    envelope.bodyOut = rpc;
                    envelope.dotNet = true;
                    envelope.encodingStyle = SoapSerializationEnvelope.XSD;
                    rpc.addProperty("contents",Base64.encode(_raw));
                    imageName="Image" + _counter + EXTENSION;
                    rpc.addProperty("FileName", imageName );
                    HttpTransport ht = new HttpTransport(serviceUrl);
                    ht.debug = true;
                    String result;
    
                    //                String str = null;
    
                    SoapObject soapObject;
    
                    try
                    {
                        ht.call(soapAction, envelope);
                        result = (envelope.getResponse()).toString();
                        //                      if((envelope.getResponse()).toString().trim().equals("OK"))
                        //                      {
                            //                         UiApplication.getUiApplication().pushScreen(new DoctorPopup());
                        //                     }
                        //                    if(result.length()==2 ||  result.equalsIgnoreCase("OK"))
                        //                     {
                            //                       UiApplication.getUiApplication().pushScreen(new DoctorPopup());
                        //                     }
    
                        if(result.length()==2)
                        {
                            UiApplication.getUiApplication().pushScreen(new DoctorPopup());
                        }
    
                        soapObject = (SoapObject) envelope.getResponse();
                        //                     Dialog.alert("soapObject" + soapObject);
                    }
                    catch(Exception ex)
                    {
                        //if we get an exception we'll just write the msg to the screen.
                        System.out.println(ex.getMessage());
                        result = ex.toString();
                    }
    
    
    
                    // Close the connections
                    out.close();
                    file.close();
                }
                catch(Exception e)
                {
                    WelcomeScreen.errorDialog("ERROR " + e.getClass() + ":  " +    e.getMessage());
                    System.out.println(e.getMessage());
                }
    
                ++_counter;
            }   
        }
    
        /**
        * A listener used for the "Cancel" button
        */
        private class CancelListener implements FieldChangeListener
        {
            /**
            * Return to the main camera screen
            */
            public void fieldChanged(Field field, int context)
            {
                UiApplication.getUiApplication().popScreen( _imageScreen );
            }
        }
    
        public final static boolean isCDMA() {
            return RadioInfo.getNetworkType() == RadioInfo.NETWORK_CDMA;
        }
    
        public final static boolean isIDEN() {
            return RadioInfo.getNetworkType() == RadioInfo.NETWORK_IDEN;
        }
    
        public static final String getIMEI() {
            if (ImageScreen.isCDMA()) {
                return ""+CDMAInfo.getESN();
            } else if (ImageScreen.isIDEN()){
                return IDENInfo.imeiToString(IDENInfo.getIMEI());
            } else {
                return GPRSInfo.imeiToString(GPRSInfo.getIMEI());
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-29 09:09

    What you request is a bit vague and odd, however I hope this can help:

    With the following piece code it's possible to get a JPEG binary data for a Bitmap (note, it is a compressed one, so the size of the data is as small as possible if compare to raw bitmap):

    Bitmap bmp = ...; // your bitmap
    int quality = 85;
    EncodedImage encodedImg = JPEGEncodedImage.encode(bmp, quality);
    byte[] data = encodedImg.getData();
    

    Then you can encode it with Base64OutputStream. See the API for sample code on how to encode.

    0 讨论(0)
提交回复
热议问题