Я создаю приложение для обработки изображений, поэтому сначала использую API платформы Android для обработки растрового объявления, а затем отправляю его на флаттер. Я использую приведенный ниже код для преобразования растрового изображения в byte []
Bitmap bitmap = BitmapFactory.decodeFile(uri.getPath());
ByteBuffer allocate = ByteBuffer.allocate(bitmap.getByteCount());
bitmap.copyPixelsToBuffer(allocate);
byte[] array = allocate.array();
а затем отправив его во флаттер, используя канал метода как Uint8List но когда я читаю его как Image.memory (). Это дает мне ошибку, поскольку
Не удалось декодировать изображение. Данные либо недействительны, либо закодированы в неподдерживаемом формате. Ниже приведен код моей основной деятельности.
package com.rahul.flutterappdomain;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import com.asksira.bsimagepicker.BSImagePicker;
import com.asksira.bsimagepicker.Utils;
import java.nio.ByteBuffer;
import io.flutter.app.FlutterFragmentActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class ActivityMain extends FlutterFragmentActivity implements BSImagePicker.OnSingleImageSelectedListener{
private static final String TAG = "DomainFilterFlutterApp";
private static final String CHANNEL = "com.rummy.io/filter";
MethodChannel methodChannel;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
methodChannel = new MethodChannel(getFlutterView(), CHANNEL);
methodChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.equals("openImagePicker")) {
showImagePickerDialog();
result.success(null);
}
}
});
}
private void showImagePickerDialog() {
String providerAuthority = "com.rahul.ffd.fileprovider";
BSImagePicker singleSelectionPicker = new BSImagePicker.Builder(providerAuthority)
.setSpanCount(4)
.setGridSpacing(Utils.dp2px(4))
.setPeekHeight(Utils.dp2px(360))
.build();
singleSelectionPicker.show(getSupportFragmentManager(), "picker");
}
@Override
public void onSingleImageSelected(Uri uri) {
Bitmap bitmap = BitmapFactory.decodeFile(uri.getPath());
ByteBuffer allocate = ByteBuffer.allocate(bitmap.getByteCount());
bitmap.copyPixelsToBuffer(allocate);
byte[] array = allocate.array();
methodChannel.invokeMethod("setImage", array);
Log.d(TAG, "onSingleImageSelected: ------------");
}
}
и код моего файла дротика
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'colors.dart';
//import 'package:image_picker/image_picker.dart';
void main(){runApp(MyApp());}
class MyApp extends StatefulWidget {
static const platform = const MethodChannel('com.rummy.io/filter');
String _image;
Uint8List _image_data ;
Future<Null> getImage() async {
platform.invokeMethod("openImagePicker");
}
@override
State<StatefulWidget> createState() {
var myAppState = MyAppState();
platform.setMethodCallHandler((MethodCall call) {
switch (call.method) {
case 'setImage':
print('setState');
myAppState.makeState(call.arguments);
print('setState');
}
});
return myAppState;
}
}
class MyAppState extends State<MyApp> {
void makeState( Uint8List imgData) {
setState(() {
widget._image_data = imgData;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: _mAppTheme,
home: Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(Icons.save),
)
],
),
body: _mBody(widget._image_data),
floatingActionButton: FloatingActionButton(
onPressed: () {
widget.getImage();
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.elliptical(12.0, 13.0))),
child: Icon(Icons.image),
),
),
);
}
double _discreteValue = 0.0;
double _discreteValue2 = 0.0;
Widget _mBody(Uint8List imgData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
child: imgData == null
? Image.asset(
'images/beauty.jpg',
fit: BoxFit.contain,
)
: /*Image.file(
File(img),
fit: BoxFit.contain,)*/
Image.memory(imgData),
),
),
new Slider(
value: _discreteValue,
min: 0.0,
max: 200.0,
divisions: 10,
activeColor: Colors.greenAccent,
label: '${_discreteValue.round()}',
onChanged: (double value) {
setState(() {
_discreteValue = value;
});}),
new Slider(
value: _discreteValue2,
min: 0.0,
max: 200.0,
divisions: 10,
activeColor: Colors.greenAccent,
label: '${_discreteValue2.round()}',
onChanged: (double value) {
setState(() {
_discreteValue2 = value;
});}),
],
),
);
}
/* Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
});
}*/
}
final ThemeData _mAppTheme = _buildAppTheme();
ThemeData _buildAppTheme() {
final ThemeData base = ThemeData.light();
return base.copyWith(
accentColor: kShrineBrown900,
primaryColor: kShrinePink100,
buttonColor: kShrinePink100,
scaffoldBackgroundColor: kShrineBackgroundWhite,
cardColor: kShrineBackgroundWhite,
textSelectionColor: kShrinePink100,
errorColor: kShrineErrorRed,
);
}
нет, я использую пользовательский сборщик изображений BSImagePicker, но это не имеет значения, потому что я получаю uri изображения, а затем декодирую его с помощью BitmapFactory
Я думаю, что лучше поставить путь изображения между Flutter и Android.
вы пытались сохранить изображение в кеш и прочитать его во флаттере?
Вы не можете передать необработанное растровое изображение в Image.memory, потому что оно не содержит достаточно информации, особенно ширины и высоты. Конструкторам изображений требуется распознанный формат файла: JPEG, PNG, GIF, анимированный GIF, WebP, Animated WebP, BMP и WBMP.
Если файл, который вы открываете здесь:
Bitmap bitmap = BitmapFactory.decodeFile(uri.getPath());
находится в одном из вышеперечисленных форматов, тогда не декодируйте его в растровое изображение Android, а скорее прочтите его дословно в массив байтов, отправьте его по каналу и используйте в качестве входных данных для конструктора изображения. (Или, если вы можете, просто передайте путь к файлу обратно в Dart и используйте dart:io и, при необходимости, path_provider, чтобы прочитать файл.)
Если вам действительно нужно передать необработанное растровое изображение в Image, то проще всего добавить заголовок Windows Bitmap (BMP). Есть пример здесь для необычного необработанного формата растрового изображения. Вашему даже не понадобится индексированная цветовая карта, поскольку у вас почти наверняка уже есть пиксели ARGB (проверьте это, проверив, что размер растрового изображения в байтах = 4 * ширина * высота).
Например: не используйте метод decodeFile, а только обычный ввод-вывод файлов Java. Однако, как было предложено, вероятно, проще передать имя файла Dart и использовать dart:io для его чтения.
У меня было такое же сообщение об ошибке. Проблема в том, что вы неправильно декодируете растровое изображение в своем Java-коде. Вот решение, которое будет работать
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
bitmap.recycle();
// And return byteArray through your MethodChannel
Подробнее на ответ @Ihor Klimov
Я конвертирую растровое изображение в java с устройства отпечатков пальцев:
ByteArrayOutputStream stream = new ByteArrayOutputStream();
fingerBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
fingerBitmap.recycle();
тогда во Flutter Dart я просто использую
Uint8List fingerImages;
void mapFingerImage(dynamic imageBytes) {
setState(() {
fingerImages = imageBytes;
});
}
Image.memory(fingerImages,
width: 100,
height: 100,
fit: BoxFit.contain,)
вы отправляете изображение из приложения Google Фото?