A Flutter package for manipulating bitmaps

Related tags

Image bitmap
Overview

transform image dog

Flutter Bitmap

Pub

A minimalist Flutter package to perform fast bitmaps operations. The focus here is to provide a cool bitmap manipulation interface.

The package standard format is RGBA32.

Bitmap uses the Dart FFI to perform operations such as contrast, brightness, saturation, and exposure.

For now, things like format encoding, EXIF and multi-frame images are not the concern of this package. If that is your need, check image. Some of the algorithms here are heavily inspired by this awesome lib.

Why this exists?

I started to use dart image to create LetsPicture (cool app, check it out) but since the beginning, I've noticed that the performance was really bad. Dart image has its own Image format, so between decoding, putting some transformations and then displaying the result on the app you had to convert the image two times (at least).

So this package is just this: We deal bitmaps (duh) and we focus only on Flutter use cases.

bitmap takes some advantages from Flutter:

  • Every image is decoded to RGBA32 by the framework trough ImageStreamListener, so we can rely on Flutter to do the decoding job;
  • Dart FFI: we are porting some of our functions to C (or C++) making it blazing fast.
  • With this package, you can easily take advantage of stuff like compute (Isolates) on only the manipulations you want to free the UI thread of heavy computation.
  • Niks Want to create your own image editor? Niks and bitmap are awesome for the job.

Alternatives

Dart image

As mentioned previously, check on pub.

Flutter Built-in ColorFilter class

Flutter has a powerful ColorFilter class (that came from skia) which can be used to put some color corrections when painting stuff on canvas. You can use a matrix to correct color (Some matrix examples here). Not every color transformation can be done through the matrix, though.

Basic usage

1. Image to Bitmap

Everything is around the Bitmap class. You can get an instance of that from any ImageProvider.

import 'package:bitmap/bitmap.dart';

Bitmap bitmap = await Bitmap.fromProvider(NetworkImage("http://pudim.com.br/pudim.jpg")); // Notice this is an async operation
You can create from a headed Uint8List:
import 'package:bitmap/bitmap.dart';

Bitmap bitmap = Bitmap.fromHeadful(imageWidth, imageHeight, theListOfInts); // Not async
Or a headless:
Bitmap bitmap = Bitmap.fromHeadless(imageWidth, imageHeight, theListOfInts); // Not async

This is useful when you are dealing with the Uint8List that ByteData generates.

You can even create a blank one
Bitmap bitmap = Bitmap.blank(imageWidth, imageHeight);

This creates a black, full transparent bitmap.

2. Applying some operations

Let's put some contrast

import 'package:bitmap/bitmap.dart';

Bitmap contrastedBitmap = bitmap.apply(BitmapContrast(0.2));;

It is possible to add several operations at once

import 'package:bitmap/bitmap.dart';
Bitmap brightBitmap = bitmap.applyBatch([
  BitmapBrightness(0.2),
  BitmapAdjustColor(
    saturation: 1.0
  ),
]);

3. Displaying/painting/saving the output

You can create two outputs from a Bitmap instance:

  • A Uint8List with no header, only the content of the file (.content property).
  • A Uint8List with a bitmap header, which Flutter can parse (.buildHeaded() method).
Displaying

To easiest way to display an image is to getting the bitmap with header and then passing it to the widget Image.memory:

// ..

Uint8List headedBitmap = bitmap.buildHeaded();

// ..
child: Image.memory(headedBitmap)
// ..
Painting

The Bitmap class has also a helper function buildImage that uses Flutter's decodeImageFromList to build a dart:ui Image. With an Image, you can paint it in a canvas (in a CustomPainter, for example).

import 'dart:ui' as ui;
// ..
ui.Image outputImage = await bitmap.buildImage();
canvas.drawImage(outputImage, Offset.zero, ui.Paint());
Saving

You can also save the image as a .bmp file (get the file content with the .buildHeaded() method). You can check also the image lib where you can save the image in several formats.

How to save files with Flutter?

Performance improvements and Dart FFI

Dart FFI

The capability of calling a c (or c++) function from dart can help us a lot in getter better performance times.

Isolates

Most of the manipulations on the bitmap take a long time to be completed. That's is because they have to iterate on every item of the bitmap. A picture with a 400px width and height sizes will generate a list of 640000 integers. This is a heavy computation. Those can be expensive. Sou you may use Isolates there to free the UI thread from all of this work.

Check the example app, where the transformations are applied through the compute function.

Important: it is noticed that the performance increases a lot when using release mode on your Flutter App

Apps using it (only one for now)

Supported operations

  • Flip vertical
  • Flip horizontal
  • Rotation
  • Resize (nearest interpolation)
  • Contrast
  • Brightness
  • Saturation
  • Exposure
  • Crop

Todo

There is a lot of work to be done:

  • Resize with other interpolations
  • Set channel
  • White balance
  • Color blend
  • Noise
  • Tones
  • ??? The sky is the limit
Comments
  • Incompatible with flutter 1.12.13+hotfix.5

    Incompatible with flutter 1.12.13+hotfix.5

    After upgrading to new flutter there's issues with the ffi file, see outcome below.

    ../../../.pub-cache/hosted/pub.dartlang.org/bitmap-0.0.5/lib/ffi.dart:22:32: Error: Method not found: 'Pointer.allocate'.
            ffi.Pointer<ffi.Uint8>.allocate(count: sourceBmp.length);
                                   ^^^^^^^^
    ../../../.pub-cache/hosted/pub.dartlang.org/bitmap-0.0.5/lib/ffi.dart:24:41: Error: The method 'asExternalTypedData' isn't defined for the class 'Pointer<Uint8>'.
     - 'Pointer' is from 'dart:ffi'.
     - 'Uint8' is from 'dart:ffi'.
    Try correcting the name to the name of an existing method, or defining a method named 'asExternalTypedData'.
        final pointerList = startingPointer.asExternalTypedData(
                                            ^^^^^^^^^^^^^^^^^^^
    ../../../.pub-cache/hosted/pub.dartlang.org/bitmap-0.0.5/lib/ffi.dart:29:21: Error: The method 'free' isn't defined for the class 'Pointer<Uint8>'.
     - 'Pointer' is from 'dart:ffi'.
     - 'Uint8' is from 'dart:ffi'.
    Try correcting the name to the name of an existing method, or defining a method named 'free'.
        startingPointer.free();
    
    opened by ryankauk 6
  • Incorrect assertion in BitmapResize

    Incorrect assertion in BitmapResize

    After update i found incorrect assertion in constructor BitmapResize.to({int? width, int? height})

    https://github.com/renancaraujo/bitmap/blob/8170945e80472395f31252f0899dd50b8c643b1c/lib/src/operation/resize.dart#L5-L12

    Assertion with correct (non-null) arguments always return false and trow assertion exception, it must be

    assert(
              width != null || height != null,
              "You have to provide either width or height to resize an image",
            );
    
    opened by StanevDev 3
  • The latest version 0.0.6 has no rotation and crop

    The latest version 0.0.6 has no rotation and crop

    I try to introduce through github

    bitmap: git: url: https://github.com/renancaraujo/bitmap.git

    But the rotateClockwise method reports an error Can you update the new version?

    opened by Moyck 3
  • Height is applied to header as negative

    Height is applied to header as negative

    Was wondering why the height is set as negative,

    https://github.com/renancaraujo/bitmap/blob/ed8df15d759eb15a4819711f7670315893fefd2a/lib/bitmap.dart#L87

    opened by ryankauk 3
  • How should the Uint8List for `Bitmap.fromHeadless` look

    How should the Uint8List for `Bitmap.fromHeadless` look

    First of all thank you for this package. However I am stuck while trying to convert an Uint8List to a bitmap. What I am trying is:

      final bitmap = Bitmap.fromHeadless(
        this.width,
        this.height,
        layer
      );
      final headed = bitmap.buildHeaded();
      final imgMem = Image.memory(headed);
      return imgMem;
    

    However the code always crashes at the buildHeaded(). Now I am wondering what the problem is and how the uint8list should be build. Is it supposed to encode RGBA in separate ints like:

    [255, 0, 0, 255]
    

    for a completely red pixel?

    opened by CaptainDario 2
  • Compile error with v0.1.2

    Compile error with v0.1.2

    Since today I'm getting this error when trying to compile my project:

    FAILURE: Build failed with an exception.                                
                                                                            
    * What went wrong:                                                      
    Execution failed for task ':bitmap:externalNativeBuildDebug'.           
    > Build command failed.                                                 
      Error while executing process /home/dlednik/Android/Sdk/cmake/3.6.4111459/bin/cmake with arguments {--build /home/dlednik/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/bitmap-0.1.2/android/.cxx/cmake/debug/armeabi-v7a --target bitmap}
      [1/2] Building CXX object CMakeFiles/bitmap.dir/home/dlednik/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/bitmap-0.1.2/ios/Classes/bitmap.cpp.o
      FAILED: /home/dlednik/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++  --target=armv7-none-linux-androideabi16 --gcc-toolchain=/home/dlednik/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=/home/dlednik/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot  -Dbitmap_EXPORTS  -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security   -O0 -fno-limit-debug-info  -fPIC -MD -MT CMakeFiles/bitmap.dir/home/dlednik/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/bitmap-0.1.2/ios/Classes/bitmap.cpp.o -MF CMakeFiles/bitmap.dir/home/dlednik/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/bitmap-0.1.2/ios/Classes/bitmap.cpp.o.d -o CMakeFiles/bitmap.dir/home/dlednik/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/bitmap-0.1.2/ios/Classes/bitmap.cpp.o -c /home/dlednik/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/bitmap-0.1.2/ios/Classes/bitmap.cpp
      In file included from /home/dlednik/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/bitmap-0.1.2/ios/Classes/bitmap.cpp:1:
      In file included from /snap/flutter/current/usr/include/c++/8/stdlib.h:36:
      In file included from /snap/flutter/current/usr/include/c++/8/cstdlib:41:
      In file included from /snap/flutter/current/usr/include/x86_64-linux-gnu/c++/8/bits/c++config.h:508:
      In file included from /snap/flutter/current/usr/include/x86_64-linux-gnu/c++/8/bits/os_defines.h:39:
      In file included from /snap/flutter/current/usr/include/features.h:448:
      /snap/flutter/current/usr/include/x86_64-linux-gnu/gnu/stubs.h:7:11: fatal error: 'gnu/stubs-32.h' file not found
      # include <gnu/stubs-32.h>                                            
                ^~~~~~~~~~~~~~~~                                            
      1 error generated.                                                    
      ninja: build stopped: subcommand failed.   
    

    Anyone else seeing this? Looks like 32bit headers are missing. I installed flutter via snap on my Ubuntu 20.04

    opened by rocinante-sys 2
  • Cannot Crop Bitmap

    Cannot Crop Bitmap

    I am trying to crop a bitmap, but I get following exception. I have tried using code from example

    Future<Uint8List> batchOperationsImageIsolate(List imageData) async {
      final Uint8List byteData = imageData[0];
      final int width = imageData[1];
      final int height = imageData[2];
    
      final Bitmap bigBitmap = Bitmap.fromHeadless(width, height, byteData);
    
      final Bitmap returnBitmap = bigBitmap.applyBatch([
        BitmapAdjustColor(
          saturation: 1.9,
        ),
        BitmapCrop.fromLTWH(
          left: 10,
          top: 10,
          width: width - 20,
          height: height - 20,
        ),
      ]);
    
      return returnBitmap.content;
    }
    
    E/flutter ( 3386): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: Bad state: Too few elements
    E/flutter ( 3386): #0      _TypedIntListMixin.setRange (dart:typed_data-patch/typed_data_patch.dart:409:7)
    E/flutter ( 3386): #1      RGBA32BitmapHeader.applyContent
    package:bitmap/src/bitmap.dart:136
    E/flutter ( 3386): #2      Bitmap.buildHeaded
    package:bitmap/src/bitmap.dart:79
    E/flutter ( 3386): #3      ImageValueNotifier.batchOperations
    package:image_editor/widgets/image_notifier.dart:179
    E/flutter ( 3386): <asynchronous suspension>
    
    opened by Malik056 2
  • How should the parameters of the black and white filter be set?

    How should the parameters of the black and white filter be set?

    Thanks to the author for writing such a great library!

    Drag the progress bar to make the picture whiter, I tried it, the effect is not good

      void updateFilterValue(value) async {
        if (_filterValue == value) {
          return;
        }
        _filterValue = value;
    
        Bitmap bitmap = await Bitmap.fromProvider(ExtendedExactAssetImageProvider('assets/images/photoShoot/ic_icon_editor_topic_example.jpg'));
        Bitmap brightBitmap = bmp.brightness(bitmap, value); // 位图亮度, 可以在-1.0和1.0之间。 0.0不执行任何操作;
        Bitmap nowThisBitmapLooksWeird = bmp.contrast(brightBitmap, 1.5); // 对比度 0~2.0的范围  default 1.0
        Bitmap finalBitmap = bmp.adjustColor(nowThisBitmapLooksWeird, saturation: 0); // 饱和度 0 1
        result = finalBitmap.buildHeaded();
    
        notifyListeners();
      }
    
    opened by paintingStyle 2
  • Update image without redraw

    Update image without redraw

    Hi, I'm trying to find a way to adjust brightness and contrast of an image, using sliders on Flutter. I tested with the library image and with that. Both works well, but needs to redraw or rebuild the screen on each change. Would be possible make changes in the image without rebuild the image on screen? In a way that's transparent for the user, i mean.

    opened by JRamos29 2
  • Crop Image

    Crop Image

    I have implemented transformation that crops the source bitmap. There are two new methods:

    • cropLTWH(bitmap, left, top, width, height) - crops to rectangle defined by top, left, width and height.
    • cropLTRB(bitmap, left, top, right, bottom) - crops to rectangle defined by top, left, right and bottom.

    I already use it in my own project and here is my use case. I have a bitmap of Minecraft skin and I needed this method to cut all the parts into separate images.

    Source bitmap:

    After calling cropTLWH(bmp, 8, 8, 8, 8):

    opened by lukerayman 2
  • it occors the error when i import 'package:bitmap/bitmap.dart';

    it occors the error when i import 'package:bitmap/bitmap.dart';

    * Error running Gradle:
    ProcessException: Process "/Users/music/Documents/.../android/gradlew" exited abnormally:
    
    > Configure project :bitmap
    WARNING: The option setting 'android.enableR8=true' is experimental and unsupported.
    The current default is 'false'
    Consider disabling R8 by removing 'android.enableR8=true' from your gradle.properties before publishing your app.
    
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    A problem occurred configuring project ':bitmap'.
    > NDK not configured. 
      Download it with SDK manager.
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    
    BUILD FAILED in 1s
      Command: /Users/music/Documents/.../android/gradlew app:properties
    
    Finished with error: Please review your Gradle project setup in the android/ folder.
    
    opened by mr-52hz 2
  • What order channel in UInt8List

    What order channel in UInt8List

    I've returned an array from C++ to Dart and got Pointer<Uint8>. Then I converted it to UInt8List using list = pointer.asTypedList(totalElementsInImg);. In C++, my Matrix image is RGBA, then totalElementsInImg equals width*height*4 After that I created Bitmap using Bitmap.fromHeadless(widget.imageWidth, widget.imageHeight, showImgList) and then bitmap.buildHeaded() to return UIntt8List for showing. **Question: **What is the order of channel pixels in list. Is [r, g, b, a, r, g, b, a, .....] or [r, r, r, ..., b, b, b, ..., g, g, g, ..., a, a, a, ...] or anything else? Please help me. Thank you

    opened by AnhPC03 0
  • Execution failed for task ':bitmap:stripDebugDebugSymbols'.

    Execution failed for task ':bitmap:stripDebugDebugSymbols'.

    Hi, I'm having real difficulty getting this package working on linux. I'm getting the following error:

    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':bitmap:stripDebugDebugSymbols'.
    > No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-androideabi
    

    I've got NDK v23 and v20 installed yet still I get this when I try to build my project.

    Any ideas? Thanks

    bug 
    opened by jimmyff 1
  • add non-asynchronous transformations in resize.dart

    add non-asynchronous transformations in resize.dart

    I want to make my image processing software run the main processing method in a compute(). Problem is, the resize() method in your library is async-only, and that trickles down into the function i want to be run in a 'compute()'. Still learning about isolates, so I'm not sure if it's absolutely necessary to have the function you're running be synchronous, but it makes things easier to grasp. Regardless, having these options be available is easy to do and gives more freedom to the developer.

    question 
    opened by nojusr 1
  • Failed to load some of the Bitmap package

    Failed to load some of the Bitmap package

    I'm getting this exception when running the app after applying Bitmap package ;

           Invalid argument(s): Failed to load dynamic library (dlopen failed: library "libbitmap.so" not found)
    

    Any idea why and how to solve this issue ?

    bug 
    opened by beautybird 1
  • flutter gallery

    flutter gallery

    I want to make a gridview that depicts all the recent pictures like in instagram's or messenger's chat, but I can't make it smooth. Do you have any idea? I should isolate also the bitmap generation from imageprovider besides the resizing, or any other solution? I think I cannot load all the Uint8Lists in the memory as there are about a few thousands picture on an average phone so that would take too much memory.

    question 
    opened by virshlee 1
Releases(0.0.3)
Owner
Renan
I do some cool stuff sometimes, some weird stuff all the time.
Renan
A simple Flutter Package to Mimic iMessage Image Picker for Flutter

A simple Flutter Package to Mimic iMessage Image Picker for Flutter

Paras Jain 64 Dec 26, 2022
A flutter package which makes it easy to track a series of images.

A flutter package which makes it easy to track a series of images.

Jaehee Kim 2 Oct 7, 2022
a package for flutter canvas paint dash line path easily.

dash_painter a package for flutter canvas paint dash line path easily. 1. DashPainter 如何使用 DashPainter 只负责对 路径 Path 的虚线化绘制,不承担组件职能。 一般用在拥有 Canvas 对象的回

FlutterCandies 22 Oct 9, 2022
Flutter package for Image Carousel It is an image carousel widget.

Snapshot Carousel Flutter package for Image Carousel It is an image carousel widget. Supported platforms Flutter Android Flutter iOS Flutter web Flutt

Mrigank Anand 12 Jun 3, 2021
A flutter package to convert any widget to an Image.

Davinci A package to convert any widget to an image which can be saved locally or can be shared to other apps and chats. ?? Preview ℹ️ Usage Prerequis

Sai Gokula Krishnan 37 Dec 20, 2022
Multi image pixker using the image_picker package in flutter

multi_image_selection A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you st

Ambaliya Avnit Karshanbhai 1 Oct 13, 2021
Flutter Package to Pick Image From Gallery or Camera

image_picker_gallery_camera Flutter Package to Pick Image From Gallery or Camera Getting Started A Flutter plugin for iOS and Android for picking imag

Sayandh KP 8 Oct 5, 2022
A flutter package for image carousels.

flutter_image_carousel A flutter package for image carousels. Supports both Asset and Network images. Example new ImageCarousel( <ImageProvider>[

Theo Bouwman 53 Aug 9, 2021
Flutter's package that comes with several popular icons packages.

icons_plus icons_plus is a package that comes with several popular icons packages. How to I know icons' name? Simple answer, using flutter's auto-sugg

Rahul Chouhan 12 Dec 13, 2022
Flutter package for image editing

You can edit image using this package and also you can create flex preview image by setting foreground to null. For now, you can use only asset files.

Berkay CEYLAN 9 Nov 21, 2022
A flutter carousel widget, support infinite scroll, and custom child widget.

carousel_slider A carousel slider widget. Features Infinite scroll Custom child widgets Auto play Supported platforms Flutter Android Flutter iOS Flut

serenader 1.4k Dec 30, 2022
A Flutter widget that paints an image and moves it at a slower speed than the main scrolling content.

A Flutter widget that paints an image and moves it at a slower speed than the main scrolling content. Installation Add dependency to your pubspec.yaml

Anatoly Pulyaevskiy 272 Dec 23, 2022
📸 Easy to use yet very customizable zoomable image widget for Flutter, Photo View provides a gesture sensitive zoomable widget. Photo View is largely used to show interacive images and other stuff such as SVG.

Flutter Photo View A simple zoomable image/content widget for Flutter. PhotoView enables images to become able to zoom and pan with user gestures such

Fire Slime Games 1.7k Jan 3, 2023
SVG parsing, rendering, and widget library for Flutter

flutter_svg Draw SVG (and some Android VectorDrawable (XML)) files on a Flutter Widget. Getting Started This is a Dart-native rendering library. Issue

Dan Field 1.5k Jan 6, 2023
A Flutter plugin for Android and iOS supports cropping images

Image Cropper A Flutter plugin for Android and iOS supports cropping images. This plugin is based on two different native libraries so it comes with d

HungHD 891 Dec 28, 2022
Download, cache and show images in a flutter app

Cached network image A flutter library to show images from the internet and keep them in the cache directory. How to use The CachedNetworkImage can be

Baseflow 2.1k Jan 3, 2023
Flutter plugin that allows you to display multi image picker on iOS and Android. 👌🔝🎉

IMPORTANT: This repository has been archived and no longer mantained. As I don't have time anymore to work on the package it became very outdated. For

Radoslav Vitanov 898 Apr 29, 2021
Use lottie in flutter for both iOS and Android

flutter_lottie Use Lottie in Flutter. Supports both iOS and Android using lottie-ios and lottie-android Current Status Supports most features that bot

Cameron Smith 160 Nov 25, 2022
A flutter plugin which provides Crop Widget for cropping images.

A flutter plugin which provides Crop Widget for cropping images. crop_your_image provides only minimum UI for deciding cropping area inside images. Other UI parts, such as "Crop" button or "Change Aspect Ratio" button, need to be prepared by each app developers.

Chooyan 96 Dec 31, 2022