草庐IT

android - 从 Android 平台发送位图到 Flutter

coder 2023-07-21 原文

我正在创建一个图像处理应用程序,因此首先使用 android 平台 api 来处理位图广告,然后将其发送到 flutter。 我正在使用下面的代码将位图转换为 byte[]

  Bitmap bitmap = BitmapFactory.decodeFile(uri.getPath());
        ByteBuffer allocate = ByteBuffer.allocate(bitmap.getByteCount());
        bitmap.copyPixelsToBuffer(allocate);
        byte[] array = allocate.array();

然后使用 Method Channel 作为 Uint8List 将其发送到 flutter 但是当我把它读成 Image.memory() 时。它给我的错误是

图像解码失败。数据无效,或者使用不受支持的格式进行编码。 以下是我的主要 Activity 的代码

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: ------------");

    }
}

和我的dart文件的代码

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,
  );
}

最佳答案

我有同样的错误信息。问题是您在 Java 代码中以错误的方式解码位图图像。这是可行的解决方案

ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
bitmap.recycle();

// And return byteArray through your MethodChannel

关于android - 从 Android 平台发送位图到 Flutter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51516310/

有关android - 从 Android 平台发送位图到 Flutter的更多相关文章

  1. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  2. ruby - 使用 Ruby 通过 Outlook 发送消息的最简单方法是什么? - 2

    我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=

  3. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  4. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

  5. ruby - 如何理解 Ruby 中的发送者和接收者? - 2

    我很难理解Ruby中sender和receiver的实际含义。它们一般是什么意思?到目前为止,我只是将它们理解为方法调用和获取其返回值的调用。但是,我知道我的理解还远远不够。谁能给我一个Ruby中发送者和接收者的具体解释? 最佳答案 面向对象中的一个核心概念是消息传递和早期概念化,这在很大程度上借鉴了计算的Actor模型。艾伦·凯(AlanKay)创造了面向对象一词并发明了最早的OO语言之一SmallTalk,他拥有voicedregretatusingatermwhichputthefocusonobjectsinsteadofo

  6. ruby - 动态扩展现有方法或覆盖 ruby​​ 中的发送方法 - 2

    假设我们有A、B、C类。Adefself.inherited(sub)#metaprogramminggoeshere#takeclassthathasjustinheritedclassA#andforfooclassesinjectprepare_foo()as#firstlineofmethodthenrunrestofthecodeenddefprepare_foo#=>prepare_foo()neededhere#somecodeendendBprepare_foo()neededhere#somecodeendend如您所见,我正在尝试将foo_prepare()调用注入

  7. ruby-on-rails - 如何通过 POST 发送多个相同的键/参数? - 2

    如果我必须在一个HTTP请求中发送一堆post参数,所有这些参数都具有相同的名称,我该如何构建要发布的data对象?想象一个带有一些复选框的表单,它们都具有相同的name属性但具有不同的值(如果它们被选中):我想用ruby​​构建它(但它需要根据在表单上选择的内容动态创建):data={"color"=>"red","color"=>"green","color"=>"blue"}然后将数据发送到某个URL:Net::HTTP.post_form(url,data)我无法控制接收端,所以我必须发送它期望接收的参数。怎么办? 最佳答案

  8. 常见网络安全产品汇总(私信发送思维导图) - 2

    安全产品安全网关类防火墙Firewall防火墙防火墙主要用于边界安全防护的权限控制和安全域的划分。防火墙•信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。防火墙是一个由软件和硬件设备组合而成,在内外网之间、专网与公网之间的界面上构成的保护屏障。下一代防火墙•下一代防火墙,NextGenerationFirewall,简称NGFirewall,是一款可以全面应对应用层威胁的高性能防火墙,提供网络层应用层一体化安全防护。生产厂家•联想网御、CheckPoint、深信服、网康、天融信、华为、H3C等防火墙部署部署于内、外网编辑额,用于权限访问控制和安全域划分。UTM统一威胁管理(Un

  9. ruby-on-rails - 如何通过 HTTParty 通过 PUT 请求发送空数组? - 2

    我有一个具有“名称”属性和“标签”属性的照片类。我的目标是在Rails中实现一个更新功能,用输入的内容替换照片的标签。例如,如果我尝试PUT一个将“标签”设置为[]的JSON对象,我希望从照片中清除任何标签。但是,当我通过HTTParty提交一个空数组作为主体参数之一时,我相信HTTParty正在将[]翻译成nil。因此,我的Rails后端的photos#update端点没有接收到任何参数“tags”。我正在寻找一种方法让HTTParty不将[]转换为nil,因为我失去了从照片中删除标签的能力。 最佳答案 这是Rails4中的一个错

  10. ruby-on-rails - 使用 HTTParty 发送多个文件 - 2

    这是使用Net::HTTP::Post工作的代码request=Net::HTTP::Post.new(url)...form_data=[['attachments[]',File.open('file1.txt')],['attachments[]',File.open('file2.txt')]]request.set_formform_data,'multipart/form-data'http.request(request)现在,我正尝试像下面那样使用httpparty,但它不起作用。body={attachments:[File.open('file1.txt'),Fil

随机推荐