drawpile / Drawpile

A collaborative drawing program
http://drawpile.net/
GNU General Public License v3.0
1.04k stars 133 forks source link

new (wild) feature: gmic support - better bucket tool+ countless image filters #178

Open blurymind opened 9 years ago

blurymind commented 9 years ago

Gmic recently got a qt port - inside krita. It made the software much more powerful than before- adding many many filters. Some of the ones that really stood out for me: https://www.youtube.com/watch?v=YigbVY9s6gU better than the bucket tool alternative to fully color your image

other interesting filters: https://plus.google.com/117441237982283011318

gmic's website http://gmic.eu/

Advantages:

-multiplatform

-gain access to hundreds of filters

-it is becoming the de facto open standard for image filters- apart of gimp and krita, other open source software is picking it up.

-way faster image coloring workflow than the bucket tool- much better algorithm. The developer has shared how it works in a paper here: http://opensource.graphics/how-to-code-a-nice-user-guided-foreground-extraction-algorithm/ http://opensource.graphics/how-to-code-a-nice-user-guided-foreground-extraction-algorithm-addendum/

disadvantages:

-Some of the filter scripts might not work in some of the software that it is implemented in

-adds incentive for new issues in the bug tracker- related to individual filters provided by gmic that are incompatible with the software

callaa commented 9 years ago

I'll take a look at this in the future. I have some preliminary ideas for a major overhaul of the paint engine for version 3.0, so I'll keep this in mind.

horkana commented 9 years ago

From reading about Krita on the kimageshop and calligra lists G'Mic seems to be very unstable on Windows at the moment.

blurymind commented 9 years ago

only the 32 bit build is unstable on windows- it is due to their compiler, not g'mic itself. They are working on it.

here is a note from gmic's author:

Well, doing the integration of a library such as G'MIC in another software will always require a bit of work, because there are so so many different ways to integrate it (all the G'MIC features?, only a subset of them?, with which type of interface?, etc.). G'MIC mainly provides a powerful image processing library, and it appears I've done one additional interface (the plug-in for GIMP), but clearly I probably won't code other interfaces by myself. I've already too much work with the core functionalities alone :) Note that for interested programmer, I've done a simple code that shows how to use the libgmic library easily : http://pastebin.com/N6beVqER Maybe that could help?

he kindly provided sample code too:

/*
 #
 #  File        : gmic_use_lib.cpp
 #                ( C++ source file )
 #
 #  Description : Show how to call the G'MIC interpreter from a C++ source code.
 #
 #  Copyright   : David Tschumperle
 #                ( http://tschumperle.users.greyc.fr/ )
 #
 #  License     : CeCILL v2.0
 #                ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html )
 #
 #  This software is governed by the CeCILL  license under French law and
 #  abiding by the rules of distribution of free software.  You can  use,
 #  modify and/ or redistribute the software under the terms of the CeCILL
 #  license as circulated by CEA, CNRS and INRIA at the following URL
 #  "http://www.cecill.info".
 #
 #  As a counterpart to the access to the source code and  rights to copy,
 #  modify and redistribute granted by the license, users are provided only
 #  with a limited warranty  and the software's author,  the holder of the
 #  economic rights,  and the successive licensors  have only  limited
 #  liability.
 #
 #  In this respect, the user's attention is drawn to the risks associated
 #  with loading,  using,  modifying and/or developing or reproducing the
 #  software by the user in light of its specific status of free software,
 #  that may mean  that it is complicated to manipulate,  and  that  also
 #  therefore means  that it is reserved for developers  and  experienced
 #  professionals having in-depth computer knowledge. Users are therefore
 #  encouraged to load and test the software's suitability as regards their
 #  requirements in conditions enabling the security of their systems and/or
 #  data to be ensured and, more generally, to use and operate it in the
 #  same conditions as regards security.
 #
 #  The fact that you are presently reading this means that you have had
 #  knowledge of the CeCILL license and that you accept its terms.
 #
*/

/*
    Note : To compile this example, using g++, use :

    g++ -o gmic_use_lib gmic_use_lib.cpp -lgmic -lfftw3
*/

/* Uncomment the two lines below if you want to use the CImg library along with the G'MIC library.
 */
//#include "CImg.h"
//using namespace cimg_library;

#include <cmath>
#include "gmic.h"

int main() {

  // First step : Create a list of input images.
  //--------------------------------------------
  std::fprintf(stderr,"\n- 1st step : Create input list of images.\n");

  gmic_list<float> images;                            // List of images, will contain all images pixel data.
  gmic_list<char> images_names;                       // List of images names. Can be left empty if no names.
  images.assign(5);                                   // Assign list to contain 5 images.
  for (unsigned int i = 0; i<images._width; ++i) {
    gmic_image<float>& img = images._data[i];
    img.assign(256,256,1,3);                          // Assign i-th image with size 256x256x1x3 (2d color image).

    std::fprintf(stderr,"    Input image %u =  %ux%ux%ux%u, buffer : %p\n",i,
                 images._data[i]._width,
                 images._data[i]._height,
                 images._data[i]._depth,
                 images._data[i]._spectrum,
                 images._data[i]._data);

    // Fill each image buffer with sinus values (with different frequencies).
    float *ptr = img._data;
    for (unsigned int c = 0; c<img._spectrum; ++c)
      for (unsigned int y = 0; y<img._height; ++y)
        for (unsigned int x = 0; x<img._width; ++x)
          *(ptr++) = std::cos(x/(1. + i))*std::sin(y/(1. + i + c));
  }

  // Second step : Call G'MIC API to process input images.
  //------------------------------------------------------
  std::fprintf(stderr,"\n- 2st step : Call G'MIC interpreter.\n");

  try {

    // Here you can call any G'MIC command you want !
    // (here, create a deformed average of the input images, and save it as a BMP file).
    gmic("-+ -n 0,255 -flower 8 -sharpen 100 -o foo1.bmp",images,images_names);

  } catch (gmic_exception &e) { // Catch exception, if an error occured in the interpreter.
    std::fprintf(stderr,"\n- Error encountered when calling G'MIC : '%s'\n",e.what());
    return 0;
  }

  // Third step (alternative) : Call G'MIC API to process input images.
  //---------------------------------------------------------------------
  std::fprintf(stderr,"\n- 3rd step (alternative) : Call G'MIC interpreter from empty instance.\n");

  gmic gmic_instance;   // Construct first an empty 'gmic' instance.

  try {

    // Here, we use the already constructed 'gmic' instance. The same instance can be used
    // several times.
    gmic_instance.run("-blur 5 -sharpen 1000 -n 0,255 -o foo2.bmp",images,images_names);
    std::fputc('\n',stderr);
    gmic_instance.run("--resize 50%,50% -to_rgba[-1] -rotate[-1] 30 -drop_shadow[-1] 0,13 "
                      "-blur_radial[0] 10% -blend alpha -o foo3.bmp",images,images_names);

  } catch (gmic_exception &e) { // Catch exception, if an error occured in the interpreter.
    std::fprintf(stderr,"\n- Error encountered when calling G'MIC : '%s'\n",e.what());
    return 0;
  }

  // Fourth step : get back modified image data.
  //---------------------------------------------
  std::fprintf(stderr,"\n- 4th step : Returned %u output images.\n",images._width);
  for (unsigned int i = 0; i<images._width; ++i) {
    std::fprintf(stderr,"   Output image %u = %ux%ux%ux%u, buffer : %p\n",i,
                 images._data[i]._width,
                 images._data[i]._height,
                 images._data[i]._depth,
                 images._data[i]._spectrum,
                 images._data[i]._data);
  }

  // Fourth step : Free image resources.
  //-------------------------------------
  images.assign(0U);

  // That's it !
  //-------------
  std::fprintf(stderr,"\n- That's it !\n");
  return 0;
}
blurymind commented 9 years ago

some information on the problem with 32 bit windows krita gmic: http://blenderartists.org/forum/showthread.php?363939-Krita-2-9-is-released!&p=2835264&viewfull=1#post2835264

Note that gimp on windows does not have this problem as it is using another compiler for the windows builds

To explain, gmic, as a filter framework, has it's own parser system, but for some reason, this parser doesn't build right on msvc, and Krita can't be build with mingw(which gmic is usually build with), this in turn results in gmic taking 5 hours to build on windows, which makes the actual bugs at the heart of this impossible to fix: the parser needing tons of space(stack size) to even read the filters, which it often doesn't have and thus results in crashes. (Amongst others)

These kind of things would be written in the release notes, but these haven't beeen written yet, you're too early.

Edit: here's the mailinglist thread, most of the unmentioned things were from irc. https://mail.kde.org/pipermail/kimageshop/2015-March/012686.html

blurymind commented 9 years ago

Btw I just found out that krita developers are implementing lazybrush https://phabricator.kde.org/T372

g'mic has it already, but they are doing it as a tool that is integrated. Might be of help later on

blurymind commented 7 years ago

Recently Gmic dev added a new filter that automatically cleans up a drawing like this: e38722cf8d5ed647bdcdb61fd47755bb21357fa3_1_690x302

That would be quite nice to have in drawpile. Also gmic's plugin has switched to QT, just so it is easier to integrate into gt apps such as krita. Read more here https://discuss.pixls.us/t/release-of-gmic-2-0-3/4513

blurymind commented 6 years ago

this is now built into krita- called a colorize mask https://www.youtube.com/watch?v=6MCnK5LofIM

You could use their implementation

askmeaboutlo0m commented 1 year ago

(I've taken over development on Drawpile, so I'm going through these tickets and organizing them.)

I don't think filters is something that fits into Drawpile, since it's whole-image/whole-layer operations, which is stuff that doesn't mix well with collaborative drawing. GMic in specific has broken on Krita a number of times, so I'd also be a bit worried about the maintenance burden in that regard.