2013-01-02 2 views
-1

서버로 보내야하는 이미지가 있습니다. 블랙 베리의 비트 맵 (jpg)을 base64 문자열로 변환하는 방법이 있습니까?검은 딸기의 비트 맵을 base64 문자열로 변환합니다.

+0

은 먼저 비트 맵을 바이트 배열로 변환합니다. 그런 다음 base64 문자열로 변환하십시오. – Signare

+0

바이트 배열로 비트 맵을 변환하려고했지만 바이트 배열로 변환하는 것은 많은 메모리를 소비합니다. –

+0

큰 이미지를 사용 하시겠습니까? – Signare

답변

6

는 당신이 요청하는 것은 그러나 나는이 도움이 될 수 있습니다 희망, 조금 애매하고 이상한 원시 비트 맵에 비교한다면 그래서 데이터의 크기가) 가능한 한 작은 :

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

그런 다음 당신이 Base64OutputStream로 인코딩 할 수 있습니다. 인코딩 방법은 API for sample code을 참조하십시오.

+0

선생님, 대단히 감사합니다,이 하나가 내가 찾은 것보다 훨씬 낫습니다. 내 이미지를 변환 할 다른 클래스를 만들 필요가 없으며 인코딩 된 이미지의 품질을 수정할 수 있습니다. –

+1

다행, 나는 도움이되었다. 마지막으로 "원시 비트 맵 바이너리"의 Base64 인코딩 데이터를 얻지 않아도됩니다. :) –

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

여기에 전체 앱을 게시하지 마십시오. 비트 맵 이미지를 인코딩하는 데 사용해야한다고 생각되는 코드를 잘라냅니다. 또한 편집 창에서 ** 모든 ** 소스 코드를 선택하고 ** {} ** 버튼을 사용하여 코드 형식을 지정하십시오. 편집기 아래에있는 미리보기에서 대답을보고 가독성이 있는지 확인하십시오. 감사. – Nate

+0

다음 번에는 이것을 명심하십시오. – Puneet

+2

다음 번에 대기 할 필요가 없습니다. 귀하의 답변 아래에 약간 ** 수정 ** 링크가있어서 언제든지 돌아가서 대답을 수정할 수 있습니다. 나는 종종 내 대답을 여러 번 편집합니다. – Nate

1

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

이것은 내 것이 아닙니다. 저는 이것을 창조하고 다른 개발자들에게 이것을 사용하게 해주신 Christian Fräschlin에게 정말 감사드립니다. 이것은 terms.에 대한 링크입니다.

내가 잊기 전에,이 제한이 있습니다. 비트 맵을 byte []에 성공적으로 변환 할 수 있으며 크기는 63kb보다 작거나 같지만 크기가 제한을 초과하면 변환 된 이미지가 변색됩니다. 그것은 압축 하나입니다, 그것은 Bitmap (주에 대한 JPEG 이진 데이터를 얻을 수있어 다음의 조각 코드와

:

관련 문제