Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Surface for 8-bit grayscale image #125

Closed
xanadupark opened this issue Nov 16, 2015 · 12 comments
Closed

Surface for 8-bit grayscale image #125

xanadupark opened this issue Nov 16, 2015 · 12 comments

Comments

@xanadupark
Copy link

Hello all,

I recently tried to use Julia/Cairo for an image generation of 8-bits gray scale.
In fact, what I need is an uint8 array with each element represent the gray scale for the further calculation. (It is conventional 8-bit grayscale image, I think)
However, I cannot find the way to make grayscale surface with Cairo.

At first, I assumed that CAIRO_FORMAT_A8 is the grayscale surface and also assumed that the data array has to be an uint8 array. However, there's error like follows:

julia> sf = CairoImageSurface(dt,2);
ERROR: MethodError: `CairoImageSurface` has no method matching CairoImageSurface(::Array{UInt8,2}, ::Int32)
   Closest candidates are:
   CairoImageSurface(::Real, ::Real, ::Integer)
   CairoImageSurface(::Array{UInt32,2}, ::Integer)

dt is Array{UInt8,2}

And then, I convert the dt array to uint32:

julia> sf = CairoImageSurface(dt,2)
ERROR: AssertionError: stride == 4w
 in CairoImageSurface at C:\Users\10189524\.julia\v0.4\Cairo\src\Cairo.jl:175

Of course, I can make the image surface with ARGB or RGB format.
Is this a bug or my short knowledge of Cairo?

Thanks in advance

@lobingera
Copy link
Contributor

CAIRO_FORMAT_A8 (see http://cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t) is 8 bit, but alpha channel only. This is usually used as a alpha mask for painting. You could e.g. use this to paint black color source to a white background with your image in the _A8 alpha map to paint a grayscale image, but the easier way is to use one of the color formats (_RGB).

@xanadupark
Copy link
Author

Thanks @lobingera.
Maybe I can use RGB surface to draw my figures.
However, I want to use 8-bit surface if possible since my target array is somewhat large one. (There will be a few 20000 * 20000 float64 array and my PC has relatively small memory.)
Also, if possible, binary b/w image will be more useful for me.
In fact, I don't need figure itself, I just want the arrays.
Is there any possible way to do this?

@timholy
Copy link
Member

timholy commented Nov 16, 2015

Is there any reason you need to use Cairo? The ColorTypes and Images packages supports 8-bit grayscale natively. In previous benchmarking, we've found julia code, especially when dealing with grayscale, to be faster than libcairo by fairly large factors (3-10 or so).

@xanadupark
Copy link
Author

@timholy Can ColorTypes/Images deal with drawing shapes/lines? What I need is to make arrays whose elements can form many "shapes" (such as rectangles or triangles...)
I'm new to Julia (just a few weeks) and I have not read the package manuals completely.
I think Images package can convert images to integer array. However, I don't know I can "draw" something with them.

@lobingera
Copy link
Contributor

@timholy, could you please link to this benchmarking?
@xanadupark, Tim is right, handling large bitmaps/images with Cairo might not be the most efficient way (i'm e.g. not sure if 8bit Alpha format isn't using 32bit with masking...). Usually Cairo is used as the step before painting or displaying and so you might e.g. need only to bring 512x512 pixels clipped to screen, but your image stored is 20000x20000. libcairo has some infrastructure for this (http://cairographics.org/manual/cairo-Raster-Sources.html) but i think it's not available in Cairo.jl right now.

@timholy
Copy link
Member

timholy commented Nov 16, 2015

@xanadupark, no, there is no drawing. You could see if Drawing.jl would be interested in a non-Cairo backend, but then someone would have to implement it.

Two benchmarks that come to mind:

@lobingera, you were on both of those threads, if you wanted links you could have provided them yourself 😛

@lobingera
Copy link
Contributor

@timholy, i'm always hoping for something more recent.

@timholy
Copy link
Member

timholy commented Nov 16, 2015

By all means, run the code in those benchmarks and report the results.

@lobingera
Copy link
Contributor

Just for the record, after copying the code Tim's code from the first thread and working around the dep warnings in 0.4.1 ->

julia> include("image-resize.jl")
Cairo:
0.046598 seconds (31 allocations: 51.400 MB, 1.75% gc time)
Julia:
0.085892 seconds (9 allocations: 6.047 MB)

@timholy
Copy link
Member

timholy commented Nov 16, 2015

Fascinating. On my machine the julia code is still faster, especially if I replace trunc with unsafe_trunc. (Back when that was written, julia's trunc was unsafe.) But the gap is now only 2x.

The difference is that the Cairo version got faster, not that the julia code (if you make that change) got slower. Nice!

@lobingera
Copy link
Contributor

I think there was some work on pixman (the SW that deals with pixel operations and blitting) especially on interpolation in finishing 1.14. But still, Cairo is not the place for image operations, but elegant and efficient image display.

@xanadupark
Copy link
Author

Thanks everybody.

I found out there is no proper Julia package at this time for my use.
I look into Drawing.jl and it seems like use Cairo as backend.
I also look into Compose package but it is somewhat complicated for me.
I think I can use some python packages to draw my arrays and use Julia for the calculation.

Thanks all for your advise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants