Compose.jl icon indicating copy to clipboard operation
Compose.jl copied to clipboard

WIP: image and bitmap implementation

Open lobingera opened this issue 8 years ago • 18 comments

Started in dcjones/Compose.jl#140 and (long time ago) dcjones/Gadfly.jl#288 this should create a basis for both an

  • image implementation (see thread) -> insert an image into a Compose context
  • bitmap implementation -> insert a matrix of colored pixels into a Compose context. (note: the definition was and is still reverse in the code ... but i use the 'new' here).

There are two implementations of backends touched here, SVG and the cairo based backends for PNG, PDF, PS and CAIROSURFACE (which can be used to render to native on-screen windows).

Two primitives and and two backends create 4 cases

  1. SVG/image: was and is implemented, should be working (at least the SVG spec claims) for png, jpeg and svg
  2. Cairo/image: is not implemented, would need at least a png to cairosurface read function. Available for files, but not for literal strings.-> work on cairo needed.
  3. SVG/bitmap: is demoed here, the bitmap is converted via Cairo to png and inserted into svg.
  4. Cairo/bitmap: works as expected.

in example/bitmap_image.jl

lobingera avatar Aug 30 '15 10:08 lobingera

This is looking good. Cairo has Cairo.read_from_png, but that requires a filename, which is awkward. You could write the data to a temporary file, but a better (and trickier) option would be to add bindings to cairo_image_surface_create_from_png_stream in Cairo.jl to read from an arbitrary IO type.

dcjones avatar Sep 02 '15 19:09 dcjones

Opening a temp file is sooo 90s... Libcairo has also cairo_image_surface_create_from_png_stream and i think this should be integrated in Cairo.jl.

lobingera avatar Sep 02 '15 21:09 lobingera

I agree with myself, Libcairo has also cairo_image_surface_create_from_png_stream but it looks like i'm failing in doing the stream callback function correctly. I could not track down how to handle the data length correctly or this is a cairo bug.

lobingera avatar Sep 06 '15 11:09 lobingera

There is another problem, the image operator in SVG (the standard) lacks a clear defintion how the content is rendered. On my computer i find already two different implementations - inkscape and librsvg. inkscape scales the image and displays rectangular pixels, librsvg (ImageMagick) filters the pixels with an interpolation.

snapshot3

lobingera avatar Sep 06 '15 12:09 lobingera

Wow I didn't realize there was such diversity in how bitmaps rendered in svg. Here's the same thing with chrome, safari, and firefox. screen shot 2015-09-06 at 11 00 26 pm screen shot 2015-09-06 at 11 00 33 pm screen shot 2015-09-06 at 11 00 41 pm

SVG has a image-rendering property, but it's only options are optimizeSpeed or optimizeQuality, and neither value seemed to do anything. You can turn off interpolation in chrome with image-rendering="pixelated" and in firefox with image-rendering="-moz-crisp-edges", but there's no option that works everywhere which is pretty unfortunate.

I guess we have to either live with that or do the scaling ourselves.

dcjones avatar Sep 07 '15 06:09 dcjones

If you push a new commit (or rebase on current master and force-push, see http://docs.julialang.org/en/stable/manual/packages/#squashing-and-rebasing), then the Travis failure on Linux should be addressed by #180.

timholy avatar Dec 23 '15 13:12 timholy

@timholy I have to admit, i didn't see this before. I need to pull from #180, or pull from master?

lobingera avatar Dec 23 '15 15:12 lobingera

Since #180 is merged to master, you can just checkout the latest master and rebase on top of that.

timholy avatar Dec 23 '15 17:12 timholy

Attempt at fixing a minor issue when using Cairo backends: https://github.com/lobingera/Compose.jl/pull/1. Thanks!

Sacha0 avatar Jan 13 '16 23:01 Sacha0

btw: (apart from being busy with other things) i stopped updating because two things are still a show stopper: Rendering of bitmap in .svg is unclear, reading a png from a stream into a surface doesn't work.

I'd really like a symmetric solution that renders the bitmap correct in both (Cairo backend and SVG backend).

lobingera avatar Jan 14 '16 11:01 lobingera

Rendering of bitmap in .svg is unclear

Are low resolution embedded bitmaps common? Is this issue significant outside of that case? Best!

Sacha0 avatar Jan 14 '16 22:01 Sacha0

Attempt at fixing another minor issue: https://github.com/lobingera/Compose.jl/pull/2. Thanks!

Sacha0 avatar Jan 15 '16 20:01 Sacha0

@Sacha0, https://github.com/dcjones/Compose.jl/pull/141#issuecomment-171799053

I can not follow. Do you mean low resolution is the rare case and we can live with the artefacts?

lobingera avatar Jan 16 '16 09:01 lobingera

Do you mean low resolution is the rare case and we can live with the artefacts?

Correct, I wonder whether that conjecture holds. To expand, I imagine the rendering differences only become important when bitmap resolution falls well below O(100dpi), and I conjecture that embedding <<100dpi bitmaps is unusual. The marked variation between browsers seems to support that conjecture.

Similarly, is there any reason to prefer one rendering mode over the others? Consistency would be nice, but if the choice of rendering mode is subjective/arbitrary (and if the cases in which it matters are marginal as above), demanding it may not be worth the implementation effort and should not prevent this otherwise-great functionality from moving forward. (Richard Gabriel's brilliant essay 'Worse Is Better' comes to mind.) Thanks, and best!

Sacha0 avatar Jan 16 '16 20:01 Sacha0

Maybe this is addressed at another point, but concerning

Are low resolution embedded bitmaps common?

I think they are quite common in data visualization, where for example you wish to visualize covariance between different components. I am thinking of plots like these: this

axsk avatar Jan 22 '16 16:01 axsk

@axsk, exactly.

lobingera avatar Jan 22 '16 17:01 lobingera

Constructions like that above are better represented as collections of vector primitives than as embedded bitmaps. Insofar as I am aware, the primary use case for embedded bitmaps is incorporation of raster graphics into vector graphics. In that context I believe the conjectures above (https://github.com/dcjones/Compose.jl/pull/141#issuecomment-172256778) hold.

This pull request meaningfully expands this package's capabilities, filling an evident void. If at some point a refined version of the provided functionality comes along, then cheers, all the better. But in the interim, having access to the valuable functionality that this pull request provides would be great.

Thoughts? Thanks and best!

Sacha0 avatar Jul 12 '16 20:07 Sacha0

@lobingera if you have time, would you be willing to rebase this on master now that we support julia 1.0? It would be great to have raster support in Compose.

tlnagy avatar Sep 08 '18 22:09 tlnagy