decodeStream devuelve null
Estoy tratando de adoptar bitmap redimensionar tutorial – la única diferencia es que yo uso decodeStream en lugar de decodeResource. Es extraño, pero decodeStream, sin ninguna manipulación, me da un bitmap obj, pero cuando paso a través de decodeSampledBitmapFromStream devuelve null por alguna razón. ¿Cómo lo soluciono?
Aquí está el código que uso:
- Android con PorterDuff para combinar imágenes
- Dibujo androide en evento táctil
- Android: ¿Cómo overlay-a-bitmap / draw-over un mapa de bits?
- Android: Obtención de un mapa de bits desde una conexión de url (graph.facebook.com) que redirige a otra url
- Dibujar mapas de bits de recursos sobre otro
protected Handler _onPromoBlocksLoad = new Handler() { @Override public void dispatchMessage(Message msg) { PromoBlocksContainer c = (PromoBlocksContainer) _promoBlocksFactory.getResponse(); HttpRequest request = new HttpRequest(c.getPromoBlocks().get(0).getSmallThumbnail()); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; InputStream stream; ImageView v = (ImageView) findViewById(R.id.banner); try { stream = request.getStream(); //v.setImageBitmap(BitmapFactory.decodeStream(stream)); Works fine Bitmap img = decodeSampledBitmapFromStream(stream, v.getWidth(), v.getHeight()); v.setImageBitmap(img); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }; public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { if (width > height) { inSampleSize = Math.round((float)height / (float)reqHeight); } else { inSampleSize = Math.round((float)width / (float)reqWidth); } } return inSampleSize; } public static Bitmap decodeSampledBitmapFromStream(InputStream res, int reqWidth, int reqHeight) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(res, null, options); options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); options.inJustDecodeBounds = false; Bitmap img = BitmapFactory.decodeStream(res, null, options); // Gives null return img; }
- ¿Cómo tener una imagen circular, centro-recortada, sin crear un nuevo mapa de bits?
- Redimensionar bitmap de Android manteniendo relación de aspecto
- Visualización de imagen de mapa de bits en Android (OpenCV)
- Convertir android.media.Image (YUV_420_888) en mapa de bits
- Cómo dibujar un mapa de bits en un lienzo, respetando los valores alfa del mapa de bits?
- ¿Dónde desasignar correctamente el mapa de bits en Android View?
- Borde sobre un mapa de bits con esquinas redondeadas en Android
- BitmapFactory.decodeStream (inputStream) devuelve siempre null cuando algunos bytes son incorrectos
El problema era que una vez que usted ha utilizado un InputStream de un HttpUrlConnection, usted no puede rebobinar y utilizar el mismo InputStream otra vez . Por lo tanto, debe crear un nuevo InputStream para el muestreo real de la imagen. De lo contrario tenemos que abortar la solicitud http.
request.abort();
Debido a que el objeto InputStream sólo se puede consumir una vez, tiene que hacer una copia profunda de un objeto InputStream cuando desea cambiar el tamaño del mapa de bits de inputStream de HttpUrlConnection, de lo contrario decodeStream devuelve null.Here es una posible solución:
HttpURLConnection urlConnection = null; InputStream in = null; InputStream in2 = null; try { final URL imgUrl = new URL(url); urlConnection = (HttpURLConnection) imgUrl.openConnection(); in = urlConnection.getInputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream(); copy(in,out); in2 = new ByteArrayInputStream(out.toByteArray()); // resize the bitmap bitmap = decodeSampledBitmapFromInputStream(in,in2); } catch (Exception e) { Log.e(TAG, "Error in down and process Bitmap - " + e); } finally { if (urlConnection != null) { urlConnection.disconnect(); } try { if (in != null) { in.close(); } if (in2 != null){ in2.close(); } } catch (final IOException e) { Log.e(TAG, "Error in when close the inputstream." + e); } } }
el código fuente de la copia del método es el siguiente:
public static int copy(InputStream input, OutputStream output) throws IOException{ byte[] buffer = new byte[IO_BUFFER_SIZE]; int count = 0; int n = 0; while (-1 != (n = input.read(buffer))) { output.write(buffer, 0, n); count += n; } return count; }
el código souce del método decodeSampledBitmapFromInputStream es el siguiente:
public static Bitmap decodeSampledBitmapFromInputStream(InputStream in, InputStream copyOfin, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(in, null, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeStream(copyOfin, null, options); }
Hay algunos problemas en las respuestas del segundo piso. Porque en el método de copy()
, inputstream
se ha utilizado, por lo que en el método de decodeSampledBitmapFromInputStream(in,copyOfIn)
, no podemos capturar el valor de options.outWidth
.
Aquí hice una corrección: Podemos convertir entre sí entre byte[]
y inputstream
Así, podemos convertir inputstream
a byte[]
, Esto se puede utilizar varias veces.
Código como sigue:
HttpURLConnection connection = null; InputStream inputStream = null; InputStream copyiInputStream1 = null; InputStream copyiInputStream2 = null; Bitmap bitmap = null; try { URL url=new URL(imageUrl); connection=(HttpURLConnection) url.openConnection(); connection.setConnectTimeout(8000);//设置连接超时inputStream = connection.getInputStream(); byte[] data = InputStreamTOByte(inputStream); try { copyiInputStream1 = byteTOInputStream(data); copyiInputStream2 = byteTOInputStream(data); } catch (Exception e) { e.printStackTrace(); } bitmap = decodeSampledBitmapFromInputStream(copyiInputStream1,copyiInputStream2); /** * 将InputStream转换成byte数组* @param in InputStream * @return byte[] * @throws IOException */ public byte[] InputStreamTOByte(InputStream in) throws IOException{ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] data = new byte[1024*16]; int count = -1; while((count = in.read(data,0,1024*16)) != -1) outStream.write(data, 0, count); data = null; return outStream.toByteArray(); } /** * 将byte数组转换成InputStream * @param in * @return * @throws Exception */ public InputStream byteTOInputStream(byte[] in) throws Exception{ ByteArrayInputStream is = new ByteArrayInputStream(in); return is; }
- Android: Crear un menú de acción rápida
- Cómo limitar el número de la misma actividad en la pila de una aplicación de Android