在黑莓中将位图转换为base64字符串

我有一个需要发送到服务器的图像。 有没有办法在黑莓中将位图(jpg)转换为base64字符串?

你要求的是有点模糊和奇怪,但我希望这可以帮助:

使用下面的片段代码,可以获得Bitmap的JPEG二进制数据(注意,它是一个压缩的,所以如果与原始位图相比,数据的大小尽可能小):

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

然后,您可以使用Base64OutputStream进行编码。 有关如何编码的示例代码 ,请参阅API 。

 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()); } } } 

找到这一个,将Bitmap转换为byte []的速度要快得多。 正是我需要的。

 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; } } 

这是您需要调用的方法。

 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); } 

这不是我的。 我非常感谢ChristianFr�schlin创建这个并让其他开发人员使用它。 这是条款的链接。

在我忘记之前,这个有一个限制。 它可以成功地将位图转换为byte [],其大小小于或等于63kb,但如果大小超过限制,则转换后的图像将变色。