1

I would like to access to the renderBox of an element and shop it to little pieces .

i am searching if i can have the element and manipulate its painting .

I am searching on how i can convert an element into a pixal array or canvas and rebuild it.

Something like that but in flutter

enter image description here

i don't know how to approach it .

1 Answers1

1

you can check this code it is working .

import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.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: 'Flutter Photo Puzzle Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  Image image;
  //double imageHeight;
  //double imageWidth;
  String networkImage = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS0ddb_rBz3oewknk6NSRvHhcds1sC9csScoaASWGFiLBytKcdvpg";

  @override
  void initState() {
    super.initState();
    image = Image.network(networkImage);
//    rootBundle.load("assets/amrdiab.jpg").then((bd) {
//      setState(() {
//        Uint8List lst = new Uint8List.view(bd.buffer);
//        print(lst);
//        print(lst.length);
//        //image = Image.memory(lst);
//
//      });
//
//    });

  }

  @override
  Widget build(BuildContext context) {
    final maxColumns = 10;
    final maxRows = 10;
    final piecesCount = maxColumns * maxRows;
    assert(maxColumns>1,"Columns must be more than 1!");
    assert(maxRows>1,"Rows must be more than 1!");

    return Scaffold(
        backgroundColor: Color(0xFFF6F6F6),
        appBar: AppBar(backgroundColor: Color(0xFFF6F6F6), elevation: 0),
        body: Column(
          children: <Widget>[

            Expanded(
              child: GridView.builder(
                  physics: BouncingScrollPhysics(),
                  padding: const EdgeInsets.all(4.0),
                  itemCount: piecesCount,
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: maxColumns,
                    childAspectRatio: maxRows/maxColumns,
                    mainAxisSpacing: 1.0,
                    crossAxisSpacing: 1.0,
                  ),
                  itemBuilder: (BuildContext context, int index) {
                    final dx = index%maxColumns;
                    final dy = (index/maxColumns).floor();
                    print("dx = $dx dy = $dy");

                    return Container(
                      color: Colors.lightBlue,
                      alignment: Alignment.center,
                      child: Transform(
                        alignment: Alignment.center,
                        transform: Matrix4.diagonal3Values(max(maxColumns,maxRows).toDouble(),
                            max(maxRows,maxColumns).toDouble(), 1.0),


                        child: ClipRect(
                          child: Align(
                            //alignment: Alignment(-1, -1),
                            alignment: Alignment(-1+(2/(maxColumns-1))*dx,-1+(2/(maxRows-1))*dy),
                            widthFactor: 1/maxColumns,
                            heightFactor: 1/maxRows,
                            child: image,
                          ),
                        ),
                      ),
                    );
                  }),
            ),
          ],
        ));
  }
}

enter image description here

Text Widget example:

enter image description here

import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.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: 'Flutter Photo Puzzle Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  Image image;
  String networkImage = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS0ddb_rBz3oewknk6NSRvHhcds1sC9csScoaASWGFiLBytKcdvpg";

  @override
  void initState() {
    super.initState();
    image = Image.network(networkImage);

  }

  @override
  Widget build(BuildContext context) {
    final maxColumns = 3;
    final maxRows = 3;
    final piecesCount = maxColumns * maxRows;
    assert(maxColumns>1,"Columns must be more than 1!");
    assert(maxRows>1,"Rows must be more than 1!");

    return Scaffold(
        backgroundColor: Color(0xFFF6F6F6),
        appBar: AppBar(backgroundColor: Color(0xFFF6F6F6), elevation: 0),
        body: Column(
          children: <Widget>[

          Text("Hi there, I am a text widget, and can be choped into pieces:)",
          style: TextStyle(fontSize: 24.0),),

            Expanded(
              child: GridView.builder(
                  physics: BouncingScrollPhysics(),
                  padding: const EdgeInsets.all(4.0),
                  itemCount: piecesCount,
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: maxColumns,
                    childAspectRatio: 7.0,
                    mainAxisSpacing: 1.0,
                    crossAxisSpacing: 1.0,
                  ),
                  itemBuilder: (BuildContext context, int index) {
                    final dx = index%maxColumns;
                    final dy = (index/maxColumns).floor();
                    print("dx = $dx dy = $dy");

                    return Container(
                      color: Colors.lightBlue,
                      alignment: Alignment.center,
                      child: Transform(
                        alignment: Alignment.center,
                        transform: Matrix4.diagonal3Values(
                          //1.0,1.0,
                            max(maxColumns,maxRows).toDouble(),
                            max(maxRows,maxColumns).toDouble(),
                            1.0),

                        child: ClipRect(
                          child: Align(
                            //alignment: Alignment(-1, -1),
                            alignment: Alignment(-1+(2/(maxColumns-1))*dx,-1+(2/(maxRows-1))*dy),
                            widthFactor: 1/maxColumns,
                            heightFactor: 1/maxRows,
                            //child: image,
                            child: Text("Hi there, I am a text widget, and can be choped into pieces:)",
                              style: TextStyle(fontSize: 8.0),
                            ),
                          ),
                        ),
                      ),
                    );
                  }),
            ),
          ],
        ));
  }
}

Edit: How to get a byte array representation of a widget to draw in a canvas? But if you want is get the byte array of any widget that is easy implemented for example this question.

let's say you want to take a screenshot of the FlutterLogo widget . wrap it in a RepaintBoundary with will creates a separate display list for its child . and provide with a key

var scr= new GlobalKey();
RepaintBoundary(
         key: scr,
         child: new FlutterLogo(size: 50.0,))

and then you can get the pngBytes by converting the boundary to an image

takescrshot() async {
  RenderRepaintBoundary boundary = scr.currentContext.findRenderObject();
  var image = await boundary.toImage();
  var byteData = await image.toByteData(format: ImageByteFormat.png);
  var pngBytes = byteData.buffer.asUint8List();
  print(pngBytes);
  }

then you can use this array to draw directly into canvas, that is also easy.

the problem is how you can manipulate this array or do what is known as Image processing , theoretically it is doable, but certainly you will need a full package for that which is not available for flutter as to my knowledge, although the example of chopping a widget into pieces can be done as I explained earlier ,

Saed Nabil
  • 6,705
  • 1
  • 14
  • 36
  • I would like to know if i can shop anywidget not a only a photo . i want to manipulate the canvas that is being painted – Mohamed hassan kadri May 21 '19 at 12:39
  • 1
    @Mohamedhassankadri any widget can be used instead of the image , it is all widgets ,check the code again you will find added portion for text widget example. – Saed Nabil May 21 '19 at 13:25
  • 1
    @Mohamedhassankadri check the edit portion of how to convert a widget into a ByteArray . – Saed Nabil May 21 '19 at 19:31