Skip to content

Instantly share code, notes, and snippets.

@plateaukao
Created April 13, 2019 05:18
Show Gist options
  • Save plateaukao/ebb5e7169dd89cc52bda338762d4997e to your computer and use it in GitHub Desktop.
Save plateaukao/ebb5e7169dd89cc52bda338762d4997e to your computer and use it in GitHub Desktop.
image remove background in flutter
Future<Uint8List> _downloadImage() async {
String dir = (await getApplicationDocumentsDirectory()).path;
File file = new File('$dir/$_filename');
if (file.existsSync()) {
var image = await file.readAsBytes();
return image;
} else {
var response = await http.get(_url,);
var bytes = response.bodyBytes;
Uint8List newPng = await removeWhiteBackground(bytes);
file.writeAsBytes(newPng);
return newPng;
}
}
Future<Uint8List> removeWhiteBackground(Uint8List bytes) async {
Img.Image image = Img.decodeImage(bytes);
Img.Image transparentImage = await colorTransparent(image, 255, 255, 255);
var newPng = Img.encodePng(transparentImage);
return newPng;
}
Future<Img.Image> colorTransparent(Img.Image src, int red, int green, int blue) async {
var pixels = src.getBytes();
for (int i = 0, len = pixels.length; i < len; i += 4) {
if(pixels[i] == red
&& pixels[i+1] == green
&& pixels[i+2] == blue
) {
pixels[i + 3] = 0;
}
}
return src;
}
@tobinharris
Copy link

This is cool. Once the background is removed, how hard would it be to crop to the new boundaries? Basically, so you don't get a ton of empty space around the image?

@pauserra99
Copy link

Hey, Img.Image is not working.

@plateaukao
Copy link
Author

@pauserraa You need to install https://pub.dev/packages/image first.

@14397faiq
Copy link

hello Sir can you please share the link of any example project of removing image background in flutter dart. it would be a very
helpful for me thanks

@FabioFS
Copy link

FabioFS commented Feb 16, 2021

That was what I was looking for! Thanks man!

@Bellukchips
Copy link

[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method 'getBytes' was called on null.

how to fix this?

@plateaukao
Copy link
Author

[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method 'getBytes' was called on null.

how to fix this?

@Belllukchips it seems your Img.Image is null?

@Bellukchips
Copy link

Bellukchips commented Mar 4, 2021

Img.Image(error) is not work, i use Image but import image/image.dart as documented

@jaykukadiya99
Copy link

This is cool. Once the background is removed, how hard would it be to crop to the new boundaries? Basically, so you don't get a ton of empty space around the image?

How to crop background?

@Alvarocda
Copy link

Alvarocda commented Aug 17, 2021

In case you are not getting the background to be turned transparent, just add this line before line 25
src.channels = Img.Channels.rgba;

@DemianGo
Copy link

DemianGo commented Dec 16, 2021

this code doesn't work, what am I doing wrong guys, please, help.

// the function returns  List<int> , but should return Future<Uint8List>, makes no sence !!?? What am I missing ?

var newPng = Img.encodePng(transparentImage) ;       
return newPng ;           // List

Spent a lot of time here, giving up =[


import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:image/image.dart' as Img;
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import 'package:flutter/material.dart';
import 'package:path/path.dart';
//import 'package:file/file.dart';
import 'dart:async';
import 'dart:io';

class CriaSticker extends StatefulWidget {
  const CriaSticker({Key? key}) : super(key: key);

  @override
  State<CriaSticker> createState() => _CriaStickerState();
}

class _CriaStickerState extends State<CriaSticker> {
  @override
  Widget build(BuildContext context) {

    dynamic img = Imagem()._downloadImage();
    dynamic teste = Imagem().removeWhiteBackground(img as dynamic);
    //Future<Image> resu = Imagem().colorTransparent(teste, 110, 110, 110);

    if (kDebugMode) {
      print(img);
    }

    return const Center(child: Text('aabc',),);
  }
}


 class Imagem {

  Future<Uint8List> _downloadImage() async {
    String dir = (await getApplicationDocumentsDirectory()).path;
    //File file = File("http://photo.tuchong.com/4870004/f/298584322.jpg");

    final ByteData imageData = await NetworkAssetBundle(Uri.parse("http://photo.tuchong.com/4870004/f/298584322.jpg")).load("");
    final Uint8List finalImg = imageData.buffer.asUint8List();

    // display it with the Image.memory widget
    //var image = await file.readAsBytes();
    return finalImg;

  }

  Future<Uint8List>   removeWhiteBackground(Uint8List bytes) async {
    Img.Image? image = Img.decodeImage(bytes);
    Img.Image transparentImage = await colorTransparent(image!, 255, 255, 255);
    var newPng = Img.encodePng(transparentImage) as Future<Uint8List> ;
    return newPng ;
  }


  Future<Img.Image> colorTransparent(Img.Image src, int red, int green, int blue) async {
    var pixels = src.getBytes();
    for (int i = 0, len = pixels.length; i < len; i += 4) {
      if(pixels[i] == red
          && pixels[i+1] == green
          && pixels[i+2] == blue
      ) {
        pixels[i + 3] = 0;
      }
    }

    return src;
  }
}

@LukaMajcenic
Copy link

LukaMajcenic commented Dec 19, 2021

@DemianGo return newPng as Uint8List;

@silvanasilvana
Copy link

@DemianGo could you do it? I've been trying for weeks and I can't !!!

@ibrahimEltayfe
Copy link

greeting for the author for sharing this code.
i modified little things in the code and it works for me, hope this works for you.

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:io';

Future<Uint8List?> removeWhiteBackground(Uint8List bytes) async {
  img.Image? image = img.decodeImage(bytes);
  img.Image? transparentImage = await colorTransparent(image!, 255, 255, 255);
  var newPng = img.encodePng(transparentImage!);
  Uint8List unit8list = Uint8List.fromList(newPng);
  return unit8list;
}


Future<Uint8List> _downloadImage() async {
  File file =File('your image path here');

  var image = await file.readAsBytes();

  return image;

}

Future<img.Image?> colorTransparent(img.Image src, int red, int green, int blue) async {
  var bytes = src.getBytes() ;
  for (int i = 0, len = bytes.length; i < len; i += 4) {
    if((bytes[i] == red&&bytes[i+1] == green&&bytes[i+2] == blue)
    ){
      bytes[i+3] = 0;
    }
  }

  return img.Image.fromBytes(src.width, src.height, bytes);
}

class RemoveBG extends StatelessWidget {
  RemoveBG({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: FutureBuilder(
        future: _downloadImage(),
        builder:(context, snapshot) => snapshot.data==null?SizedBox.shrink(): FutureBuilder(
          future: removeWhiteBackground(snapshot.data!),
          builder:(context, snapshot1) =>  snapshot1.data==null?SizedBox.shrink():Container(
            child: Center(
                child: Image.memory(snapshot1.data!,)
            ),
          ),
        ),
      ),
    );
  }
}

@nit900
Copy link

nit900 commented Oct 22, 2022

I don't get it I cant get Img.Image to work at all and cant find the library online anywhere. Did they change it to something else?

@zynxyzouo
Copy link

I don't get it I cant get Img.Image to work at all and cant find the library online anywhere. Did they change it to something else?

import 'package:image/image.dart' as img;←
the img.Image will work

@Alvarocda
Copy link

It's working on version 3.2.0
Not working on latest version 4.0.15

@KoOVERLINE
Copy link

KoOVERLINE commented May 26, 2023

Adding it to the 25th line does not make it transparent.

Future<Img.Image> colorTransparent(Img.Image src, int red, int green, int blue) async{
    src.channels = Img.Channels.rgba;
    var pixels = src.getBytes();
    for (int i = 0, len = pixels.length; i < len; i += 4) {
      if(pixels[i] == red
          && pixels[i+1] == green
          && pixels[i+2] == blue
      ) {
        pixels[i + 3] = 0;
      }
    }

    return src;
  }

@KoOVERLINE
Copy link

This is All code.

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:remove_background/remove_background.dart';
import 'dart:ui' as ui;

import 'package:syncfusion_flutter_signaturepad/signaturepad.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';

import 'package:image/image.dart' as Img;


class SignPage2 extends StatefulWidget {
  const SignPage2({super.key});

  @override
  State<SignPage2> createState() => _SignPage2State();
}

class _SignPage2State extends State<SignPage2> {

  final GlobalKey<SfSignaturePadState> signatureGlobalKey = GlobalKey();


  ui.Image? signImage;

  void _handleClearButtonPressed() {
    signatureGlobalKey.currentState!.clear();
  }


  //백그라운드 제거
  Future<Uint8List> removeWhiteBackground(Uint8List bytes) async {
    Img.Image? image = Img.decodeImage(bytes);
    Img.Image transparentImage = await colorTransparent(image!, 255, 255, 255);
    var newPng = Img.encodePng(transparentImage);
    return Uint8List.fromList(newPng);
  }

  Future<Img.Image> colorTransparent(Img.Image src, int red, int green, int blue) async{
    src.channels = Img.Channels.rgba;
    var pixels = src.getBytes();
    for (int i = 0, len = pixels.length; i < len; i += 4) {
      if(pixels[i] == red
          && pixels[i+1] == green
          && pixels[i+2] == blue
      ) {
        pixels[i + 3] = 0;
      }
    }

    return src;
  }

  void _handleSaveButtonPressed() async {
    final data =
        await signatureGlobalKey.currentState!.toImage(pixelRatio: 3.0);
    final bytes = await data.toByteData(format: ui.ImageByteFormat.png);

    Uint8List signImage;

    print('>>>데이터의 타입 : ${data.runtimeType}');
    if( bytes != null ){
      signImage = await removeWhiteBackground(Uint8List.fromList(bytes.buffer.asUint8List()));

      final result = await ImageGallerySaver.saveImage(Uint8List.view(signImage.buffer));

      ByteData item = await cutImage(context: context, image: data);
      
    }

    print('>>>바이트 형식 : ${bytes.runtimeType}');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("SYNCFUSION FLUTTER SIGNATUREPAD"),
      ),
      body: Center(
        child: Column(
          children: [
            Container(
              width: double.infinity,
              height: 400,
              decoration: BoxDecoration(
                border: Border.all(
                  width: 1.0, color: Colors.black, style: BorderStyle.solid
                ),
                color: Colors.blue,
              ),
              child: SfSignaturePad(
                key: signatureGlobalKey,
                backgroundColor: Colors.white,
              ),
            ),
            ElevatedButton(onPressed: _handleSaveButtonPressed, child: Text('사진 저장')),
            ElevatedButton(onPressed: _handleClearButtonPressed, child: Text('사진 초기화')),

          ],
        ),
      ),
    );
  }
}

@hydev777
Copy link

hydev777 commented Oct 2, 2023

This coded worked for me, thanks!

@Aishh2211
Copy link

Its not removing background , making the shade of white greyish

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment