Closed CiaranOMara closed 3 years ago
The reason behind this is that PNGFiles internally calls the C library libpng by passing the pointer of the data, which further requires the data to be a "typical" C-like contiguous memory block. Thus for any other custom array types that have different memory layout, we need to explicitly convert it to Array
type via collect
.
PNGFiles.save("sm.png", collect(coloured))
This is a simple workaround with some overhead. If the sparse array can't be fit into memory then we don't have simple solution here unless someone digs into the low level of libpng to take advantage of buffers, or implement another PNG IO package using pure Julia.
I guess we could check img isa StridedArray
and if not call collect
, but arguably this might be one of those cases where it's better if the caller makes that decision since passing a really large sparse array might have some unfortunate consequences.
I was afraid that a C-like contiguous memory block would be expected. Maybe memory maps will provide a workaround... I'd need to restructure the MWE to manage memory consumption.
using Mmap
using PNGFiles
using SparseArrays
using ColorSchemes
using ColorVectorSpace # supplies zero(::ColorTypes.RGB{Float64}).
sm = sparse([1,2,3], [4,5,6], [7,8,9])
open("mmap.bin", "w+") do io
mm = Mmap.mmap(io, Matrix{eltype(ColorSchemes.bwr.colors)}, size(coloured))
mm .= get(ColorSchemes.bwr, sm)
Mmap.sync!(mm)
PNGFiles.save("mm.png", mm)
end
Indeed another possibility is to use memory maps outright.
I'm not sure where to report this one. Essentially I was hoping to create a PNG from a SparseArray. The MWE follows.
Below is the error produced from the example.
I think there is a missing unsafe_convert method for SparseArray?