Skip to content

Add simpler api for creating a dart:ui Image of a given width and height and by setting individual pixel values #148597

Closed
@mmcdon20

Description

@mmcdon20

Use case

Currently in flutter there is not a convenient way to create an Image of a given width and height, and then set individual pixels on said Image before displaying it.

Consider the following example program:

import 'dart:async';
import 'dart:math';
import 'dart:typed_data';
import 'dart:ui';

import 'package:flutter/material.dart' hide Image;

void main() async {
  final Completer<Image> completer = Completer<Image>();

  const int w = 640;
  const int h = 640;
  final Int32List img = Int32List(w * h);

  final Random random = Random();

  double x = 0;
  double y = 0;

  for (int i = 0; i < 200000; i++) {
    double tmpx, tmpy;
    final double r = random.nextDouble();

    if (r <= 0.01) {
      tmpx = 0;
      tmpy = 0.16 * y;
    } else if (r <= 0.08) {
      tmpx = 0.2 * x - 0.26 * y;
      tmpy = 0.23 * x + 0.22 * y + 1.6;
    } else if (r <= 0.15) {
      tmpx = -0.15 * x + 0.28 * y;
      tmpy = 0.26 * x + 0.24 * y + 0.44;
    } else {
      tmpx = 0.85 * x + 0.04 * y;
      tmpy = -0.04 * x + 0.85 * y + 1.6;
    }

    x = tmpx;
    y = tmpy;

    final int col = (w / 2 + x * w / 11).round();
    final int row = (h - y * h / 11).round();

    img[row * w + col] = Colors.green.value;
  }

  decodeImageFromPixels(
    img.buffer.asUint8List(),
    w,
    h,
    PixelFormat.bgra8888,
    completer.complete,
  );

  runApp(RawImage(image: await completer.future));
}

As far as I know, this is the only available api for this in flutter today. It is a bit awkward because you have to use a 1 dimensional array (Int32List), when conceptually an Image is a 2 dimensional array. You want to be able to easily set the value of a pixel at a given x and y coordinate. Also decodeImageFromPixels feels a bit awkward as well, having to use a Completer to retrieve the Image.

You can compare this program to the same program written in many other languages and frameworks: https://rosettacode.org/wiki/Barnsley_fern. In many other languages there is a an api for this along the lines of image = Image(width, height) and image.setPixel(x, y, color), for example the BufferedImage in the Java example.

There aren't any existing packages on pub.dev for this (as far as I can tell), It would be possible to write a package to help with this, but it seems like something that should be in the framework itself.

Proposal

If there was a class for this, lets say we call it ImageBuffer, it's usage might look like the following:

import 'dart:math';
import 'dart:ui';

import 'package:flutter/material.dart';

void main() async {
  final ImageBuffer img = ImageBuffer(640, 640);

  final Random random = Random();

  double x = 0;
  double y = 0;

  for (int i = 0; i < 200000; i++) {
    double tmpx, tmpy;
    final double r = random.nextDouble();

    if (r <= 0.01) {
      tmpx = 0;
      tmpy = 0.16 * y;
    } else if (r <= 0.08) {
      tmpx = 0.2 * x - 0.26 * y;
      tmpy = 0.23 * x + 0.22 * y + 1.6;
    } else if (r <= 0.15) {
      tmpx = -0.15 * x + 0.28 * y;
      tmpy = 0.26 * x + 0.24 * y + 0.44;
    } else {
      tmpx = 0.85 * x + 0.04 * y;
      tmpy = -0.04 * x + 0.85 * y + 1.6;
    }

    x = tmpx;
    y = tmpy;

    img.setPixel(
      (img.width / 2 + x * img.width / 11).round(), // x position
      (img.height - y * img.height / 11).round(),   // y position
      Colors.green.value,                           // color value
    );
  }

  runApp(RawImage(image: await img.decode()));
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    a: imagesLoading, displaying, rendering imagesc: new featureNothing broken; request for a new capabilityengineflutter/engine repository. See also e: labels.r: solvedIssue is closed as solvedteam-engineOwned by Engine team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions