#android #flask #server #android-volley
#Android #flask #сервер #android-volley
Вопрос:
Я пытаюсь создать приложение для Android, которое отправляет изображение, полученное с помощью телефона, на сервер локального хоста, работающий на flask. Я пытаюсь сохранить качество изображения, поскольку я буду выполнять некоторую обработку изображений в фоновом режиме, поэтому я использую многосоставный запрос Volley. Но поскольку я отправляю строку растрового изображения в кодировке base64 в качестве одного параметра, я получаю сообщение об ошибке из сокета, поскольку канал java.net.socketexception не работает.
Я уже пытался уменьшить размер изображения, я также попытался просто отправить строку «hi» вместо закодированного растрового изображения. Когда я это сделал, я получил ответ типа «E / Volley: [80295] BasicNetwork.performRequest: неожиданный код ответа 500».
public byte[] getFileDataFromDrawable(Bitmap bitmap) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 50, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
private void uploadBitmap(final Bitmap bitmap) {
final String tags = "image";
String url="http://192.168.43.36:5000/recog";
VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, url,
new Response.Listener<NetworkResponse>() {
@Override
public void onResponse(NetworkResponse response) {
try {
JSONObject obj = new JSONObject(new String(response.data));
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
String imgString = Base64.encodeToString(getFileDataFromDrawable(bitmap),
Base64.NO_WRAP);
params.put("content", imgString);
// params.put("content","hi");
return params;
}
// @Override
// protected Map<String, byte[]> getByteData() {
// Map<String, byte[]> params = new HashMap<>();
// params.put("content", getFileDataFromDrawable(bitmap));
// return params;
// }
};
Volley.newRequestQueue(this).add(volleyMultipartRequest);
}
Код, который я использую в файле flask, выглядит следующим образом:-
@app.route("/recog", methods=["POST"])
def get_face():
json1= request.get_json()
s=json1['content']
return jsonify(message="Done")
Я ожидаю, что base64 будет декодирован в файле flask и сохранен как изображение на локальном устройстве.
Ответ №1:
когда вы печатаете s в соответствии с печатью (ами), что у вас есть?. Это серия строк в кодировке base64
В python 2.7
import base64
@app.route("/recog", methods=["POST"])
def get_face():
json1= request.get_json()
s=json1['content']
fh = open("imageToSave.png", "wb")
fh.write(s.decode('base64'))
fh.close()
return jsonify(message="Done")
или вы можете попробовать
import base64
@app.route("/recog", methods=["POST"])
def get_face():
json1= request.get_json()
s=json1['content']
with open("imageToSave.png", "wb") as fh:
fh.write(s.decode('base64'))
return jsonify(message="Done")
Как для Python 2.7, так и для Python 3.x вы также можете попробовать
import base64
with open("imageToSave.png", "wb") as fh:
fh.write(base64.decodebytes(s))
или вы можете попробовать
with open("imageToSave.png", "wb") as fh:
fh.write(base64.decodebytes(s.encode()))
Помните: всегда проверяйте свой код, чтобы избежать сообщения об ошибке идентификации
Комментарии:
1. Спасибо. Использование request.get_data() давало мне raw в виде байтов, затем я использовал werkzeug.datastructures, чтобы перевести мои данные в словарную форму. Теперь я могу получить доступ к точной строке.
2. мой ответ также будет работать, как только вы получите свое изображение из словаря данных
3. Да, первоначальная ошибка, которую я получал, заключалась в том, что flask не смог правильно собрать отправленные на него данные.
4. значит ли это, что мое решение решило вашу проблему. почему вы не принимаете это как ответ
5. Я спросил, знает ли кто-нибудь, почему я получаю эту ошибку, и в вашем ответе показаны различные методы сохранения данных в изображении. Ошибка заключалась в том, что я пытался получить данные, которые не были отправлены в формате json в виде объекта json, из-за чего я не получал никаких данных на стороне моего сервера. Это было решено с помощью структуры данных werkzeug для получения данных. Извините, если говорить прямо, но ваш ответ не был решением вопроса, который я задал, я поблагодарил вас за то, что вы ответили.
Ответ №2:
Ребята, я решил проблему. Проблема возникла из-за того, что я пытался получить доступ к форме / многочастным данным, отправленным клиентом через request.get_json(), что неверно. Вместо этого я использовал werkzeug.datastructures для преобразования данных в словарь и доступа к необходимым частям.
Мой текущий код в flask выглядит следующим образом:
from werkzeug.datastructures import ImmutableMultiDict
@app.route("/recog", methods=["POST"])
def get_face():
data = dict(request.form)
img=data['content']
imgdata = base64.b64decode(img)
filename = 'some_image.jpg'
with open(filename, 'wb') as f:
f.write(imgdata)
return jsonify(message="Done")