bitmap 0.1.2 icon indicating copy to clipboard operation
bitmap: ^0.1.2 copied to clipboard

Bitmap is a fast and minimalistic lib that heelps you to manipulate image on Flutter apps.

example/lib/main.dart

import 'dart:async';
import 'dart:typed_data';

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image',
      theme: ThemeData(
        primarySwatch: Colors.orange,
      ),
      home: MyHomePage(
        title: "Pans",
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({
    Key? key,
    required this.title,
  }) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ImageValueNotifier imageValueNotifier = ImageValueNotifier();

  @override
  void initState() {
    super.initState();
    imageValueNotifier.loadImage();
  }

  void flipHImage() {
    if (imageValueNotifier.value != null) {
      imageValueNotifier.flipHImage();
    }
  }

  void flipVImage() {
    if (imageValueNotifier.value != null) {
      imageValueNotifier.flipVImage();
    }
  }

  void rotateClockwiseImage() {
    if (imageValueNotifier.value != null) {
      imageValueNotifier.rotateClockwiseImage();
    }
  }

  void rotateCounterClockwiseImage() {
    if (imageValueNotifier.value != null) {
      imageValueNotifier.rotateCounterClockwiseImage();
    }
  }

  void rotate180Image() {
    if (imageValueNotifier.value != null) {
      imageValueNotifier.rotate180Image();
    }
  }

  void contrastImage() {
    if (imageValueNotifier.value != null) {
      imageValueNotifier.contrastImage();
    }
  }

  void brightnessImage() {
    if (imageValueNotifier.value != null) {
      imageValueNotifier.brightnessImage();
    }
  }

  void adjustColorImage() {
    if (imageValueNotifier.value != null) {
      imageValueNotifier.adjustColorImage();
    }
  }

  void batchOperations() {
    if (imageValueNotifier.value != null) {
      imageValueNotifier.batchOperations();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        onTap: () {
          imageValueNotifier.reset();
        },
        child: Center(
          child: ValueListenableBuilder<Bitmap?>(
            valueListenable: imageValueNotifier,
            builder: (BuildContext context, Bitmap? bitmap, Widget? child) {
              if (bitmap == null) {
                return const CircularProgressIndicator();
              }
              return Column(
                children: <Widget>[
                  SafeArea(
                    top: true,
                    child: Image.memory(
                      bitmap.buildHeaded(),
                    ),
                  ),
                  const Text("Tap image to reset"),
                  Text("ImageSize ${bitmap.width}"),
                ],
              );
            },
          ),
        ),
      ),
      floatingActionButton: Buttons(
        flipHImage: flipHImage,
        flipVImage: flipVImage,
        rotateClockwiseImage: rotateClockwiseImage,
        rotateCounterClockwiseImage: rotateCounterClockwiseImage,
        rotate180Image: rotate180Image,
        contrastImage: contrastImage,
        brightnessImage: brightnessImage,
        adjustColorImage: adjustColorImage,
        batchOperations: batchOperations,
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class Buttons extends StatelessWidget {
  const Buttons({
    Key? key,
    required this.flipHImage,
    required this.flipVImage,
    required this.rotateClockwiseImage,
    required this.rotateCounterClockwiseImage,
    required this.rotate180Image,
    required this.contrastImage,
    required this.brightnessImage,
    required this.adjustColorImage,
    required this.batchOperations,
  }) : super(key: key);

  final VoidCallback flipHImage;
  final VoidCallback flipVImage;
  final VoidCallback rotateClockwiseImage;
  final VoidCallback rotateCounterClockwiseImage;
  final VoidCallback rotate180Image;
  final VoidCallback contrastImage;
  final VoidCallback brightnessImage;
  final VoidCallback adjustColorImage;
  final VoidCallback batchOperations;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 20),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Row(
            children: <Widget>[
              TextButton(
                onPressed: flipHImage,
                child: const Text(
                  "Flip horizontal",
                  style: TextStyle(fontSize: 10),
                ),
              ),
              TextButton(
                onPressed: flipVImage,
                child: const Text(
                  "Flip vertical",
                  style: TextStyle(fontSize: 10),
                ),
              ),
              TextButton(
                onPressed: contrastImage,
                child: const Text(
                  "Contrast +",
                  style: TextStyle(fontSize: 10),
                ),
              ),
            ],
          ),
          Row(
            children: <Widget>[
              TextButton(
                onPressed: brightnessImage,
                child: const Text(
                  "Brightness +",
                  style: TextStyle(fontSize: 10),
                ),
              ),
              TextButton(
                onPressed: adjustColorImage,
                child: const Text(
                  "AdjustColor +",
                  style: TextStyle(fontSize: 10),
                ),
              ),
            ],
          ),
          Row(
            children: <Widget>[
              TextButton(
                onPressed: rotateClockwiseImage,
                child: const Text(
                  "Rotate Clock +",
                  style: TextStyle(fontSize: 10),
                ),
              ),
              TextButton(
                onPressed: rotateCounterClockwiseImage,
                child: const Text(
                  "Rotate Clock -",
                  style: TextStyle(fontSize: 10),
                ),
              ),
              TextButton(
                onPressed: rotate180Image,
                child: const Text(
                  "Rotate 180",
                  style: TextStyle(fontSize: 10),
                ),
              ),
            ],
          ),
          Row(
            children: <Widget>[
              TextButton(
                onPressed: batchOperations,
                child: const Text(
                  "Batch operations (saturation + crop)",
                  style: TextStyle(fontSize: 10),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

// stores headless contents
class ImageValueNotifier extends ValueNotifier<Bitmap?> {
  ImageValueNotifier() : super(null);

  late Bitmap initial;

  void reset() {
    value = initial;
  }

  void loadImage() async {
    const ImageProvider imageProvider = const AssetImage("assets/street.jpg");

    value = await Bitmap.fromProvider(imageProvider);
    initial = value!;
  }

  void flipHImage() async {
    final temp = value!;
    value = null;

    final Uint8List converted = await compute(
      flipHImageIsolate,
      [temp.content, temp.width, temp.height],
    );

    value = Bitmap.fromHeadless(temp.width, temp.height, converted);
  }

  void flipVImage() async {
    final temp = value!;
    value = null;

    final converted = await compute(
      flipVImageIsolate,
      [temp.content, temp.width, temp.height],
    );

    value = Bitmap.fromHeadless(temp.width, temp.height, converted);
  }

  void rotateClockwiseImage() async {
    final temp = value!;
    value = null;

    final converted = await compute(
      rotateClockwiseImageIsolate,
      [temp.content, temp.width, temp.height],
    );

    value = Bitmap.fromHeadless(temp.height, temp.width, converted);
  }

  void rotateCounterClockwiseImage() async {
    final temp = value!;
    value = null;

    final converted = await compute(
      rotateCounterClockwiseImageIsolate,
      [temp.content, temp.width, temp.height],
    );

    value = Bitmap.fromHeadless(temp.height, temp.width, converted);
  }

  void rotate180Image() async {
    final temp = value!;
    value = null;

    final converted = await compute(
      rotate180ImageIsolate,
      [temp.content, temp.width, temp.height],
    );

    value = Bitmap.fromHeadless(temp.width, temp.height, converted);
  }

  void contrastImage() async {
    final temp = value!;
    value = null;

    final Uint8List converted = await compute(
      contrastImageIsolate,
      [temp.content, temp.width, temp.height],
    );

    value = Bitmap.fromHeadless(temp.width, temp.height, converted);
  }

  void brightnessImage() async {
    final temp = value!;
    value = null;

    final Uint8List converted = await compute(
      brightnessImageIsolate,
      [temp.content, temp.width, temp.height],
    );

    value = Bitmap.fromHeadless(temp.width, temp.height, converted);
  }

  void adjustColorImage() async {
    final temp = value!;
    value = null;

    final Uint8List converted = await compute(
      adjustColorsImageIsolate,
      [temp.content, temp.width, temp.height],
    );

    value = Bitmap.fromHeadless(temp.width, temp.height, converted);
  }

  void batchOperations() async {
    final temp = value!;
    value = null;

    final Uint8List converted = await compute(
      batchOperationsImageIsolate,
      [temp.content, temp.width, temp.height],
    );

    value = Bitmap.fromHeadless(temp.width - 20, temp.height - 20, converted);
  }
}

Future<Uint8List> flipHImageIsolate(List imageData) async {
  final Uint8List byteData = imageData[0];
  final int width = imageData[1];
  final int height = imageData[2];

  final bigBitmap = Bitmap.fromHeadless(width, height, byteData);
  final returnBitmap = bigBitmap.apply(BitmapFlip.horizontal());

  return returnBitmap.content;
}

Future<Uint8List> flipVImageIsolate(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.apply(BitmapFlip.vertical());

  return returnBitmap.content;
}

Future<Uint8List> rotateClockwiseImageIsolate(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.apply(BitmapRotate.rotateClockwise());

  return returnBitmap.content;
}

Future<Uint8List> rotateCounterClockwiseImageIsolate(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.apply(BitmapRotate.rotateCounterClockwise());

  return returnBitmap.content;
}

Future<Uint8List> rotate180ImageIsolate(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.apply(BitmapRotate.rotate180());

  return returnBitmap.content;
}

Future<Uint8List> contrastImageIsolate(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 returnBitmap = bigBitmap.apply(BitmapContrast(1.2));

  return returnBitmap.content;
}

Future<Uint8List> brightnessImageIsolate(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.apply(BitmapBrightness(0.1));

  return returnBitmap.content;
}

Future<Uint8List> adjustColorsImageIsolate(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.apply(
    BitmapAdjustColor(
      blacks: 0x00000000,
      saturation: 1.9, // 0 and 5 mid 1.0
    ),
  );

  return returnBitmap.content;
}

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;
}
70
likes
120
pub points
91%
popularity

Publisher

verified publisher iconblue-fire.xyz

Bitmap is a fast and minimalistic lib that heelps you to manipulate image on Flutter apps.

Repository (GitHub)

Documentation

API reference

License

Icon for licenses.MIT (LICENSE)

Dependencies

ffi, flutter

More

Packages that depend on bitmap