studio - obtener imagen almacenada en mysql desde android
Cómo enviar datos de imágenes al servidor desde Android (5)
Intento escribir una aplicación de Android que saque una foto, coloque los datos (byte []) en un objeto junto con algunos metadatos, y publíquelos en un servidor AppEngine donde se mantendrá en un almacén de datos como un blob. Realmente no quiero guardar la imagen como un archivo en Android (a menos que sea absolutamente necesario). Busqué soluciones pero no apareció nada claro o específico. Mis preguntas son:
- ¿Cómo publico el objeto en mi servlet? Específicamente cómo serializar correctamente el objeto y obtener la salida serializada a un HttpPost o algo similar.
- una vez que persista el blob en el almacén de datos, ¿cómo podré recuperarlo como una imagen para mostrar en una página web?
Los ejemplos de código serían muy útiles. Además, si el enfoque que estoy tomando es demasiado complicado o problemático, sugiera otros enfoques (por ejemplo, guardar la imagen como archivo, publicarla en el servidor y luego eliminarla).
La biblioteca Android Asynchronous Http proporciona un método para cargar archivos en un servicio web. Lo he usado en mis proyectos con gran éxito.
Parece que necesita un método de servicio web que tome un parámetro de ID y devuelva un archivo. Debería almacenar sus blobs en la tabla de la base de datos indexada con ID para que puedan ser referenciados.
1. Puedes codificar el byte [] a base64 usando:
http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html
2. Envíe esos datos con una solicitud HTTP POST a su servlet de AppEngine.
3. Configure AppEngine para aceptar un servlet.
4. Luego, tiene la opción de guardarlo en el almacén de datos o en la tienda de blob. - Prefiero la tienda de blob para este tipo de cosas.
5. Descodifique el lado del servidor de cadena base64.
6. Desde allí, tendrás que cortar la cuerda en pedazos más pequeños y escribir cada pieza en la tienda de blob.
Aquí hay un código para escribirlo en la tienda de blob.
byte[] finalImageArray = null;
try {
finalImageArray = Base64.decode(finalImageData.getBytes()); //finalImageData is the string retrieved from the HTTP POST
} catch (Base64DecoderException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try{
FileService fileService = FileServiceFactory.getFileService();
AppEngineFile file = fileService.createNewBlobFile("image/png");
FileWriteChannel writeChannel = fileService.openWriteChannel(file, true);
int steps = (int) Math.floor(finalImageArray.length/1000);
int current = 0;
for(int i = 0; i < 1000; i++){
writeChannel.write(ByteBuffer.wrap(Arrays.copyOfRange(finalImageArray, current, steps+current)));
current = current + steps;
}
writeChannel.write(ByteBuffer.wrap(Arrays.copyOfRange(finalImageArray, current, finalImageArray.length))); //The reason it''s cut up like this is because you can''t write the complete string in one go.
writeChannel.closeFinally();
blobKey = fileService.getBlobKey(file);
if(blobKey == null)
blobKey = retryBloBKey(file); //My own method, AppEngine tends to not return the blobKey once a while.
}
catch(Exception e){
logger.log(Level.SEVERE,e.getMessage());
}
return blobKey.getKeyString();
Escriba un servlet donde recupere los datos de imagen con la clave provista.
Disfruta de tu hermoso código :)
// La razón por la que lo guardo en binario es porque eso me da opciones para jugar con la API de la imagen, también puedes elegir guardarla en el formato base64.
Como el código es proporcionado por tres personas para que pueda seleccionar cualquiera de ellos (o obtendrá un montón de ejemplos en google). Hay tres posibilidades 1) primero tienes imagen en tu tarjeta sd
2) está descargando la imagen del servidor y luego enviando
3) Las imágenes se almacenan en DataBase como blob
El mejor enfoque teniendo en cuenta cada caso-
1) Si su imagen está almacenada en una tarjeta SD, simplemente fecth image Convierta en mapa de bits -> byteArray -> Cadena y envíela al servidor
2) Si está descargando imágenes desde el servidor y luego enviando a otra URL. Luego descargue todas las URL de imágenes almacenadas en la tabla de bases de datos. Más adelante cuando necesite enviar a la URL de recuperación del servidor, descargue la imagen y almacénela en memoria caché. Luego, envíela de manera similar. servidor y actualizar la memoria caché
3) Se recomienda no almacenar una gran cantidad de imágenes en DB. Pero en caso de que tenga la necesidad de hacerlo, entonces getBlob se convierte en una matriz de bytes y se envía al servidor.
Leyendo desde sdcard
List<Integer> drawablesId = new ArrayList<Integer>();
int picIndex=12345;
File sdDir = new File("/sdcard/pictures");
File[] sdDirFiles = sdDir.listFiles();
for(File singleFile : sdDirFiles)
{
Drawable.createFromPath(singleFile.getAbsolutePath());
/ you can create Bitmap from drawable
}
Espero que te ayude
No estoy seguro si esto es lo que desea, pero enviará una imagen de la misma manera que su navegador enviaría una imagen como parte de un formulario. Tendrá que descargar httmime-4.1.3.jar y agregarlo como una biblioteca referenciada en su proyecto.
Bitmap bm;//whatever bitmap you are trying to send
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bm.compress(CompressFormat.JPEG, 75, bos);
byte[] data = bos.toByteArray();
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("http://yourwebsite.com/whatever");
ByteArrayBody bab = new ByteArrayBody(data, "image name");
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("photo", bab);//"photo" is the name of the field that the image is submitted as.
postRequest.setEntity(reqEntity);
try {
HttpResponse response = httpClient.execute(postRequest);
} catch (ClientProtocolException e) {
Log.e("asdf", e.getMessage(), e);
} catch (IOException e) {
Log.e("asdf", e.getMessage(), e);
}
Solo necesita hacer un Http-FileUpload que en un caso especial de un POST. No hay necesidad de uuencode el archivo. No es necesario usar un lib / jar especial. No es necesario guardar el objeto en el disco (independientemente de que el siguiente ejemplo lo esté haciendo)
Encontrará una muy buena explicación de Http-Command y como su enfoque especial "carga de archivos" bajo
Usando java.net.URLConnection para disparar y manejar solicitudes HTTP
El archivo carga la muestra de allí sigue (mira "enviar archivo binario") y es posible agregar algunos datos complementarios, ya sea
String param = "value";
File textFile = new File("/path/to/file.txt");
File binaryFile = new File("/path/to/file.bin");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "/r/n"; // Line separator required by multipart/form-data.
URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
OutputStream output = connection.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important!
// Send normal param.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=/"param/"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF);
writer.append(param).append(CRLF).flush();
// Send text file.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=/"textFile/"; filename=/"" + textFile.getName() + "/"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF).flush();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(textFile), charset));
for (String line; (line = reader.readLine()) != null;) {
writer.append(line).append(CRLF);
}
} finally {
if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
}
writer.flush();
// Send binary file.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=/"binaryFile/"; filename=/"" + binaryFile.getName() + "/"").append(CRLF);
writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getName()).append(CRLF);
writer.append("Content-Transfer-Encoding: binary").append(CRLF);
writer.append(CRLF).flush();
InputStream input = null;
try {
input = new FileInputStream(binaryFile);
byte[] buffer = new byte[1024];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
output.flush(); // Important! Output cannot be closed. Close of writer will close output as well.
} finally {
if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}
writer.append(CRLF).flush(); // CRLF is important! It indicates end of binary boundary.
// End of multipart/form-data.
writer.append("--" + boundary + "--").append(CRLF);
} finally {
if (writer != null) writer.close();
}
En cuanto a la segunda parte de tu pregunta. Cuando se carga con éxito el archivo (uso los archivos comunes de apache), no es un gran problema entregar un blob como imagen.
Esta es la forma de aceptar un archivo en un servlet
public void doPost(HttpServletRequest pRequest, HttpServletResponse pResponse)
throws ServletException, IOException {
ServletFileUpload upload = new ServletFileUpload();
try {
FileItemIterator iter = upload.getItemIterator (pRequest);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String fieldName = item.getFieldName();
InputStream stream = item.openStream();
....
stream.close();
}
...
Y este código ofrece una imagen
public void doGet (HttpServletRequest pRequest, HttpServletResponse pResponse) throws IOException {
try {
Blob img = (Blob) entity.getProperty(propImg);
pResponse.addHeader ("Content-Disposition", "attachment; filename=abc.png");
pResponse.addHeader ("Cache-Control", "max-age=120");
String enc = "image/png";
pResponse.setContentType (enc);
pResponse.setContentLength (img.getBytes().length);
OutputStream out = pResponse.getOutputStream ();
out.write (img.getBytes());
out.close();
Espero que este código fragmentos ayuden a responder tus preguntas