“This is the second day of my participation in the First Challenge 2022, for more details: First Challenge 2022”.

preface

Of course, the first reaction of most people (including me) to this question would be something like this:

Sorry about the wrong picture, it should be this:

Now, a small need during the refactoring process reminds me of this solution:

Let’s put aside the facts of cost, manpower, feasibility, etc., is this really not feasible? 🤪

There seems to be a bit of 🤏

Here do not talk about pupil picture how to deal with first, if make a picture to you really, how should handle?

In Flutter, the image theme color should be analyzed and extracted.

In the original, in fact, there have been a lot of applications to achieve the image theme color extraction operation, which shows that the scheme is at least possible, the possibility is not small; (For example, Android Palette)

By international convention, it’s time to copy native code again:

Palette source code parsing

The principle of Palette is not complicated, skip to the start of the parse, you can see that it is not a lot of code, and there is a more detailed annotation:

The following steps are briefly summarized according to the comments:

  • 1, zoom compression picture, there is no need to whole so big, and according to the final zoom effect synchronous calculation of information such as the area;
  • 2. Call getPixelsFromBitmap to parse the pixel information of the picture and store it in the array;
  • 3. Construct ColorCutQuantizer and calculate what the theme colors are:
    • 1. Downgrade the color from RGB888 to 565(you don’t need that much detail anyway)
    • 2, according to the structure of the filter, remove the color value does not need to calculate and analyze;
    • 3. Judge whether the color value after filtering meets the requirements:
      • 1. If the number of filtered colors is less than the set maximum number of colors, the result is directly returned;
      • 2. If the number of filtered color values is greater than the set maximum number of colors, then call quantizePixels to quantify the color values:
        • 1, construct a class named VBox, used to store the maximum and minimum color values and other information, convenient to obtain the average value (in plain English is to divide the region, put the region information into this class)
        • 2. Continuously search for the midpoint of color value, split vBoxes and update the saved region information until the number of vboxes after segmentation reaches the specified maximum number of colors;
        • 3. Calculate the average color value in each VBox and return it to get the theme color;

Think a flow chart would look good?

In a word:

To put it bluntly, in fact, the idea is very simple, the picture after compression processing, divided into specified blocks, finally return the average color of each block;

So the next thing to do is translate the native code

If only the translation, in fact, not a problem, a brief description of the Android approach is different parts:

The tool class is not a big problem, the difference is mainly in the image data reading:

In Android, the operation of images is basically done through bitmap; Therefore, the bitmap.getPixels method is used to read image pixel information.

In Flutter, Image information is obtained using an Image. Take a local file as an example:

PS: In addition, I found a small point, if I do not pay attention to it, it can still bring a certain amount of trouble:

On Android, the color value is an int;

In Dart, it is also int:

But Android, or Java ints and Dart ints, have different ranges;

For example, FF0000, which is also red, is 4294901760 in Dart and -65536 in Java

So when developing Dart, don’t let the int range you’re familiar with in Java get in your way, or you’ll end up like me when you first see it.

conclusion

The list is sorted by the number of pixels in the block:

The first test image was this one:

The Android:

Flutter of:

How does my version of flutter feel closer to the theme color… In this Android native, the black area is the third highest weight, look at the image. Is that right? …

But the weight of the highest part, there is no objection ~ ~ ~ of course, generally we will not choose the weight of the low part as a theme color

The next thing to do is to analyze the ImageProvider section to see how the Image loading process of flutter works. Finally, how to apply this tool class to the Image widget

Finally, we go back to the question mentioned in the title. After dealing with such a series of examples, WE believe that we have recognized this scheme and reached a unified conclusion:

Meet to mention this kind of demand of the product, or first dozen better, who won to listen to who


Update: It turns out there’s actually a library that does this ………… Completion of this topic

PaletteGenerator