Conversión de imagen de Base64 en android resultando en imagen dañada
Necesito cargar JSON al servidor así que intenté codificarlo usando base64 y después enviándolo a través de JSON pero mientras decodificando la imagen en el extremo del servidor, la imagen aparece corrompida. Incluso probé en línea base64 a los convertidores de imagen, resultado siendo el mismo.
Aquí está mi código de la actividad donde estoy codificando la imagen a base64 después de que sea elegido de la galería o de la cámara fotográfica.
- Gestione diferentes tipos de respuesta JSON desde el mismo punto final en RetroFit
- No se puede analizar JSonArray en Android
- Retrofit 2: Obtener el cuerpo de JSON from Response
- LoganSquare analiza en objeto o mapa genérico
- Extraño error de API de IAP de lotes de Google Play
package com.paaltao.activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Base64; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import com.android.volley.AuthFailureError; import com.android.volley.NetworkError; import com.android.volley.NoConnectionError; import com.android.volley.ParseError; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.ServerError; import com.android.volley.TimeoutError; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonObjectRequest; import com.github.mrengineer13.snackbar.SnackBar; import com.kbeanie.imagechooser.api.ChooserType; import com.kbeanie.imagechooser.api.ChosenImage; import com.kbeanie.imagechooser.api.ImageChooserListener; import com.kbeanie.imagechooser.api.ImageChooserManager; import com.paaltao.R; import com.paaltao.classes.SharedPreferenceClass; import com.paaltao.network.VolleySingleton; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import cn.pedant.SweetAlert.SweetAlertDialog; import static com.paaltao.extras.Keys.UserCredentials.KEY_ACCESS_TOKEN; import static com.paaltao.extras.Keys.UserCredentials.KEY_DATA; import static com.paaltao.extras.Keys.UserCredentials.KEY_EMAIL; import static com.paaltao.extras.Keys.UserCredentials.KEY_ERROR_CODE; import static com.paaltao.extras.Keys.UserCredentials.KEY_ERROR_NODE; import static com.paaltao.extras.Keys.UserCredentials.KEY_HAS_SHOP; import static com.paaltao.extras.Keys.UserCredentials.KEY_MESSAGE; import static com.paaltao.extras.Keys.UserCredentials.KEY_OPEN_SHOP; import static com.paaltao.extras.Keys.UserCredentials.KEY_SELLER_ID; import static com.paaltao.extras.Keys.UserCredentials.KEY_SIGN_IN; import static com.paaltao.extras.Keys.UserCredentials.KEY_TOKEN; import static com.paaltao.extras.Keys.UserCredentials.KEY_VENDOR; import static com.paaltao.extras.urlEndPoints.BASE_URL; import static com.paaltao.extras.urlEndPoints.OPEN_SHOP; import static com.paaltao.extras.urlEndPoints.SIGN_UP; import static com.paaltao.extras.urlEndPoints.UAT_BASE_URL; public class OpenShopActivity extends AppCompatActivity implements ImageChooserListener { Button selectCoverButton; private ImageChooserManager imageChooserManager; String imagePath,sellerID,accessToken,encodedImage; ImageView coverImageArea; private SweetAlertDialog dialog; private Bitmap myBitmap; private EditText shopName,aboutShop,contactNo,shopAddress,city,state,postalCode,shopURL; SharedPreferenceClass preferenceClass; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_open_shop); Toolbar toolbar = (Toolbar) this.findViewById(R.id.app_bar); toolbar.setTitleTextColor(Color.WHITE); this.setSupportActionBar(toolbar); this.setTitle("open a shop!"); initialize(); onItemClick(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_open_shop, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_launch){ if (validationCheck()) { sendJsonRequest(); } } //noinspection SimplifiableIfStatement return super.onOptionsItemSelected(item); } public void initialize(){ selectCoverButton = (Button)findViewById(R.id.select_cover_button); coverImageArea = (ImageView)findViewById(R.id.shop_cover_image); shopName = (EditText)findViewById(R.id.shop_name); aboutShop = (EditText)findViewById(R.id.about_shop); contactNo = (EditText)findViewById(R.id.shop_contact); shopAddress = (EditText)findViewById(R.id.shop_street_name); city = (EditText)findViewById(R.id.shop_city_name); state = (EditText)findViewById(R.id.shop_state); postalCode = (EditText)findViewById(R.id.shop_pincode); shopURL = (EditText)findViewById(R.id.shop_url); preferenceClass = new SharedPreferenceClass(this); } public boolean validationCheck(){ if(shopName.getText().toString().length() == 0) shopName.setError("Please provide a shop name"); else if (aboutShop.getText().toString().length() == 0) aboutShop.setError("Please provide some info about your shop"); else if(contactNo.getText().toString().length() == 0 && contactNo.getText().toString().length()>10) contactNo.setError("Please provide 10 digit contact number"); else if(postalCode.getText().toString().length() == 0) postalCode.setError("Please provide a postal code"); else if(shopURL.getText().toString().length() == 0 && shopURL.getText().toString().contains(".")) shopURL.setError("Please provide a shop url"); else return true; return false; } public void sendJsonRequest(){ final JSONObject jsonObject = new JSONObject(); final JSONObject openShop = new JSONObject(); try{ jsonObject.put("accessToken","67drd56g"); jsonObject.put("merchantName","Arindam Dawn"); jsonObject.put("userEmail","[email protected]"); jsonObject.put("shopName",shopName.getText().toString()); jsonObject.put("aboutShop",aboutShop.getText().toString()); jsonObject.put("contactNo",contactNo.getText().toString()); jsonObject.put("street",shopAddress.getText().toString()); jsonObject.put("city",city.getText().toString()); jsonObject.put("state",city.getText().toString()); jsonObject.put("country","India"); jsonObject.put("pincode",postalCode.getText().toString()); jsonObject.put("shopUrl",shopURL.getText().toString()); if (encodedImage != null){ jsonObject.put("coverImage",encodedImage);} else jsonObject.put("coverImage",""); openShop.put("openShop", jsonObject); } catch (JSONException e) { e.printStackTrace(); } RequestQueue requestQueue = VolleySingleton.getsInstance().getRequestQueue(); JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,getRequestUrl(),openShop,new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject jsonObject) { Log.e("error",jsonObject.toString()); Log.e("json", openShop.toString()); if (encodedImage != null){ Log.e("base64",encodedImage); } parseJSONResponse(jsonObject); } },new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { if (volleyError instanceof TimeoutError || volleyError instanceof NoConnectionError) { new SnackBar.Builder(OpenShopActivity.this) .withMessage("No Internet Connection!") .withTextColorId(R.color.white) .withDuration((short) 6000) .show(); } else if (volleyError instanceof AuthFailureError) { //TODO } else if (volleyError instanceof ServerError) { //TODO } else if (volleyError instanceof NetworkError) { //TODO } else if (volleyError instanceof ParseError) { //TODO } } }); requestQueue.add(jsonObjectRequest); } public static String getRequestUrl() { return UAT_BASE_URL + OPEN_SHOP; } public void onItemClick(){ selectCoverButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { chooseImageDialog(); Log.d("TAG","image chooser selected!"); selectCoverButton.setText("Change cover image"); } }); } public void parseJSONResponse(JSONObject jsonObject) { if (jsonObject == null || jsonObject.length() == 0) { return; } try { JSONObject dataObject = jsonObject.getJSONObject(KEY_DATA); JSONObject openShopObject = dataObject.getJSONObject(KEY_OPEN_SHOP); JSONObject errorNodeObject = dataObject.getJSONObject(KEY_ERROR_NODE); sellerID = openShopObject.getString(KEY_SELLER_ID); accessToken = openShopObject.getString(KEY_ACCESS_TOKEN); String errorCode = errorNodeObject.getString(KEY_ERROR_CODE); String message = errorNodeObject.getString(KEY_MESSAGE); if (message.contains("Already Registered")){ new SnackBar.Builder(OpenShopActivity.this) .withMessage("A shop already exist with this username") .withTextColorId(R.color.white) .withDuration((short) 6000) .show(); } else{ new SnackBar.Builder(OpenShopActivity.this) .withMessage("Congrats! Shop Created") .withTextColorId(R.color.white) .withDuration((short) 6000) .show(); preferenceClass.saveVendorLoginSuccess("true"); Intent intent = new Intent(OpenShopActivity.this,HomeActivity.class); startActivity(intent); finish(); } } catch (JSONException e) { e.printStackTrace(); } } public void chooseImage(){ imageChooserManager = new ImageChooserManager(this, ChooserType.REQUEST_PICK_PICTURE); imageChooserManager.setImageChooserListener(this); try { imageChooserManager.choose(); } catch (Exception e) { e.printStackTrace(); } } public void snapImage(){ imageChooserManager = new ImageChooserManager(this, ChooserType.REQUEST_CAPTURE_PICTURE); imageChooserManager.setImageChooserListener(this); try { imageChooserManager.choose(); } catch (Exception e) { e.printStackTrace(); } } public void chooseImageDialog(){ dialog = new SweetAlertDialog(this, SweetAlertDialog.NORMAL_TYPE); dialog.setTitleText("Choose your Cover Image") .setContentText("Choose from gallery or take a camera snapshot!") .setConfirmText("Gallery") .setCancelText("Camera") .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { @Override public void onClick(SweetAlertDialog sDialog) { chooseImage(); } }) .setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() { @Override public void onClick(SweetAlertDialog sDialog) { snapImage(); } }) .show(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK && (requestCode == ChooserType.REQUEST_PICK_PICTURE || requestCode == ChooserType.REQUEST_CAPTURE_PICTURE)) { imageChooserManager.submit(requestCode, data); } } @Override public void onImageChosen(final ChosenImage image) { runOnUiThread(new Runnable() { @Override public void run() { if (image != null) { // Use the image imagePath = image.getFileThumbnail(); Log.d("TAG","PATH is"+imagePath); myBitmap = BitmapFactory.decodeFile(imagePath); ImageView myImage = (ImageView) findViewById(R.id.shop_cover_image); myImage.setImageBitmap(myBitmap); coverImageArea.setVisibility(View.VISIBLE); dialog.hide(); dialog.dismiss(); Bitmap bm = BitmapFactory.decodeFile(imagePath); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.JPEG, 75, baos); //bm is the bitmap object byte[] b = baos.toByteArray(); encodedImage = Base64.encodeToString(b, Base64.NO_WRAP); Log.e("addy",encodedImage); // // InputStream inputStream = null;//You can get an inputStream using any IO API // try { // inputStream = new FileInputStream(imagePath); // } catch (FileNotFoundException e) { // e.printStackTrace(); // } // byte[] bytes; // byte[] buffer = new byte[8192]; // int bytesRead; // ByteArrayOutputStream output = new ByteArrayOutputStream(); // try { // assert inputStream != null; // while ((bytesRead = inputStream.read(buffer)) != -1) { // output.write(buffer, 0, bytesRead); // } // } catch (IOException e) { // e.printStackTrace(); // } // bytes = output.toByteArray(); // image.getFilePathOriginal(); // image.getFileThumbnail(); // image.getFileThumbnailSmall(); } } }); } @Override public void onError(final String reason) { runOnUiThread(new Runnable() { @Override public void run() { // Show error message } }); } }
La cadena codificada base64 que consigo en el registro es
/ 9J / 4AAQSkZJRgABAQAAAQABAAD / 2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL / 2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL / wAARCAJQBBwDASIAAhEBAxEB / 8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL / 8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4 + Tl5ufo6erx8vP09fb3 + Pn6 / 8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL / 8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3 + Pn6 / 9oADAMBAAIRAxEAPwDwgKVPWplwVxnn + dWp7ITHcp2t / OqrxtGxVxyKhNM0qUpQ3GkY4pRxSh2H8VLvPcD8qoyGbAenWpY7jPySjjsfSmLgk / Lg0EA5ppgSSwbRkYI9RVdsgjNSxyvGcfeT0qZ4UuF3xEZHUd6YEIPHvQTxRgjINLxjNJIBKDzQPSl9 aBgBkUAdeaFozg0WEL3pPpS44PNJjjtQgDvR1FLtx3poGKAHc801qeKaeaAQ08I1OjGE6Ux8 + WfrT1zt96AArkEUkbZwD1FOpjArhx260wQ5l2njoaQHing7l65qMgqcUDJo2wOtEq7l3AfWkjG4HANSDuCODTEVQOaUZ59qc6bT0pqnPP50gFHY04c5B60nqKUE4z + dALQcoHUml2AZwwJNMH3jz + VKckH2oAXacdM4pQMHNIMggg0oZjkZzj1oAQHkjHNLniniQd0GDR + 7Ochh9DmgBo64zS5yD3pyxxkcSgf7wP8A9eneQQSQ6tn0NADCPSnIcdRwOxoMTjqpH4UD3oAmURuCWUrn + 7Uy2yn7km72PBqCMBlI9KtwRbsY5oJsMaAqMFSD7ipI4 / lOBk1oQW0hUgA4x3qwunF0JKYPbHFMCfwy1tbQ6kXnjhuXi2QlxnJ7j9BT / Ek6TC2gRY2aKIGR1HViOmeen + NU4rSSOdGKggN371DcpI1zOrLtUscHHvQp9At1MHZnkipMYPWpJIyoJKn8qiIxzmga1GOBg1EQc9eKdzznFBHPGcUrgCSsm4Zyp6g9DQY0cblbY390 / wBKj9aDzimMU7kOHGKAwAJpRIQCGwyjsaXyg2Sh59D1oEmMBwv1pBjODQMg4IxQP4uaQwAxml9qPTmk65 / KgAP3sdBQDwc / hSDJU0u3AoAAQBQDknFNwc0oPNABj5frSY5pc56mk7daBADnmk7Yo / lSA0AKOtSQqWNRqMnAq5BEzkKgyScAUhj4LR7lyqcY71b / ALMlQZ38fSuz8KeE3u7eQ8bQOWJ6mr83gm + QzN5bGNRlNpBz9fyp + xm1dEqaR5NOrJcSB + oOKjwMYq1qbq + oXDIwZd2AQeDjjI / KqowMk0loUKB + VHfNHagUgQYPSjr9KXHWm + vpQAuMA + tIOmKUrz15ox1 / nRcAHU0nTjHWlo6ZI60AAXt0oyDz1o68mkA96EAd6DyaUHAO DmkFMA6DmjtQDmjr36UwEAzxR + NKMjOKBGT / AI0ANz6UoBPSpPLAPJ4pwCgHFAEaIcfSn4PFOU4zx + dAzj2oQtBuzPan7BGvJ + tBKx8k5PYVXdmYkk8UDFeYEnHT1NNLE / xU3b1pQDQAZ5pRRgmlx70AAB5zTxgDrQBz0phOKBXFz3pAT0pR3pQuQaAGL941OYx5Oe9RRrwTVnGLccGkMqnjPOaOaeVpApoAaAW4FP2hPrTgAmTjJphJY0xbjDkk80D5RS5K00tnNACdM00cg05RnrTsAA1IyMDNOCgA807txTTk8CmAetA60oXHU04EAHaM + 5osALGWPLBR6mmkhSQvPuaGI / ibNND4PA49aFoA4KWO4nP1owOcmk3FuKAODmgAAHUUEUopD9aAEx70uOM0UAUwEzQT1oxjNJzk0gEpfwoA60nQdaAF6Zpppx6dab170CNwcfT2pssKSrhhn3p2MnFOFcq0PYcU9zKubZ4T6r60xOnXIrYZFZSDzmqU9mV5QZHp6VrGd9Diq4ZrWJVI9DQDx9KTnJFL6HpWiOWwZz1pu5oWDpx7VJgHPH1qOT7tFwLcbxXYIPyP / OoZY2iOGBxUajPPQjvVqO5DgR3A46BqoLFcdDR1q2LYRBycMjKcNVQHrStYAA5JpVHvRSrxTQw6ZoGMUpHGKQDrSEJjIPpQBweKXFJ0zQAq96TjB9aWkxkHpQMY33APepB92oiOQM96lzgGhCG5FHsaAOaXvTAjB2Njsae43KSOopSm8EflSRuRkHqKAGo + 3pU6MT361DIgHI6Gljb1pgTyJvj9xVfgE5q1G2RioZo9pNICPHBxSjjHpTFJp + ePY0AKOhB7UueOOfWmA5I / WnKOOvegBy9xTg3IP4GmZzz6UdOKAHY6jsKULTAe + acDwc0ALjApcnGc03J4pBnnmgCYM4Bw3Wnqx2gHn8KiU / qKcDQBZTA424PtWnZKjMo3MP1rKi + XnrnrWrp2GIAHekB6 J4R8Hza8HMCgopG5jwFruY / hXCttKZZx5oAMYj5B9Qc / 5 / lR8L5PsehxEKM3dyUP0VR / Vq9KZQ4ww4p3FY8pv / hQs219Ou1dDIATIpUgevviuE1zwzcaNqE0E4RmU / ejbIP + fevoqa2LQlIXMRHIIrjtU8GwX + mXJc7LyFmYPnh1681LHY + fL6Fg75wRWJPEBuIIGP1rtdf0OeC5dfKJwf4T1rkb6MpkbSCPWiLJSMwocccj2pP4ufSnY5pgbqOo96saEHA / GjIz0pflPUYNG3k4IpDGYG00uz3oIwRxS54JosAoZip3ruH6il8n5NyHdz93vUe7GB3NOEhwSO1O4rCHOOnNC8HGKlEkbtiZSePvL1psibSWjIdOxHaiwXGE8kDpTf8APSjBP / 16XmkFhPUUgwB / KjkA9jSDk0IYdMik6UpHFJxk0AGeKOtIRke9PjTJ9hQA + NQc8da6Tw5o8899F5kZVXA2E / z / ACrAjXcwAr1rR4IxYWstsVX90o3KeenPNLmUXditc3bBZ7SJLe0gHlIO46 + 9cv8AEPxtNbae + jwnbczriZh1SM9vq38vqKzfFfiS90O5tlsrtRLkl1OGx6ZB6da8 / Urua + upbm4cyzSsWd26sfWuh4hONokRhbcgPU0ClAzSbeuK5zQXHFA60AGgA88UgAdDRijPPApATQA4fr60dv6U0d6X8aYwB / Ok4ANLgk8DigISaEIQDrSetP2AdTS5Ve2aAIwM0uxqUvxxSGQt1NAhwUdzQSue9R7iBQOB60xj / MweAKTLEnJpAPU08d + KAEAA6U4c + 9KqbjgVMqKiMzHao7 + v0ppCuQOCi5pnmkqQevrTpZd5IUYQdB601lZskKcfSkFhnJpMe9LjFA7jvQMQetKMjpS4 / WnAe1AhBk0vTPFOyMcUjGgY0nPrQOhpw5FKB3H60CEAOOlOAypP8qlVc9v0qaK0MhwOvp60rjKkUZIIxV + K13xYdwoB71ctdJlds7MC .
Pero es una imagen corrupta. Se necesita ayuda !
- Java.lang.IllegalArgumentException: Caracteres ilegales en la consulta
- Cómo comprobar el doble valor está vacío o no
- El análisis de Json con gson devuelve un objeto nulo
- Cómo recibir valores json (por ejemplo: nombre de usuario y contraseña enviar como json desde una aplicación android) en Mvc 4 Web api
- Envío de datos de Android a servidor con datos JSON
- Jackson ObjectMapper Definiciones de definiciones conflictivas (Android.Graphics.Bitmap)
- Android analiza json de url y lo almacena
- BufferedReader mientras lee datos Json
Está bien que funcione para mí. Tengo la imagen correcta después de haber decodificado en la segunda actividad. Sólo para comprobar tengo un ImageView en Act1 y aquí lo convierto en Base64String pasarlo como una cadena de Act2 y Act2 (en la segunda actividad tengo un robot de Android en la vista de imagen) i decodificar la imagen de base 64 y establecer el mapa de bits que Tengo la descodificación.
Código de primera actividad:
public class ActivityImageBase64 extends Activity { ImageView ivOriginal; String imageInBase64; private Bitmap mBitmap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_image_base64); ivOriginal = (ImageView) findViewById(R.id.ivAct1); ivOriginal.setDrawingCacheEnabled(true); } public void start(View v){ mBitmap = ivOriginal.getDrawingCache(); ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArray); byte[] byteArr = byteArray.toByteArray(); imageInBase64 = Base64.encodeToString(byteArr, Base64.DEFAULT); System.out.println(imageInBase64); Intent intent = new Intent(ActivityImageBase64.this, ActivityImageBase64_2.class); intent.putExtra("image", imageInBase64); startActivity(intent); } }
Código en la segunda actividad (descodificar la cadena de mapa de bits)
public class ActivityImageBase64_2 extends Activity { ImageView ivBase64Image; private String base64Image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_activity_image_base64_2); ivBase64Image = (ImageView) findViewById(R.id.ivAndroidBot); base64Image = getIntent().getStringExtra("image"); byte[] decodedString = Base64.decode(base64Image, Base64.DEFAULT); Bitmap base64Bitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); ivBase64Image.setImageBitmap(base64Bitmap); } }
- Android Studio – PDFRendererBasic – No se puede reemplazar sample.pdf?
- Pantalla débil e interacción de bloques con hojas de fondo