View Full Version : ImageMagick writer/reader
Myrsloik
4th August 2014, 22:07
I made a simple image reader and writer since people don't have much luck with the existing ones.
Usage examples:
core.imwri.Read('E:/testdir/testimg000001.png', alpha=False)
core.imwri.Write(main, 'PNG32', 'E:/testdir/testimg%06d.png')
Documentation (https://raw.githubusercontent.com/vapoursynth/vapoursynth/master/doc/plugins/imwri.rst)
imwri test9 32bit (https://www.dropbox.com/s/viie4ztrn45dbqy/imwri-r41-win32.7z?dl=1)
imwri test9 64bit (https://www.dropbox.com/s/wti4n0y4wvwibal/imwri-r41-win64.7z?dl=1)
sneaker_ger
4th August 2014, 23:35
How is the dllpath thing supposed to work after the plugin should've already been loaded?
Myrsloik
5th August 2014, 00:17
How is the dllpath thing supposed to work after the plugin should've already been loaded?
That's a very good question. Basically ImageMagick decided that normal library ideas were too mundane.
So you not ONLY need to link against imagemagick using your standard .lib files in windows. The linking gives you access to a function in imagemagick so you can tell imagemagick where to find all its other dlls after the main dll has been loaded. It's dll hell illustrated.
A normal library (which this is most certainly not) simply would've loaded all its parts at once.
sneaker_ger
5th August 2014, 09:30
Well, I can't even get past LoadPlugin because of missing dlls even when they are in the same directory as imwri.dll.
Myrsloik
5th August 2014, 10:34
I'll look at it a bit more later but this is how I tested it:
I only used vspipe, I made sure both the script and all the plugin files are in the same directory AND that the working directory is the script directory.
I'll see if I can modify the source a bit and use mingw instead for the test versions as well...
sneaker_ger
5th August 2014, 13:11
Running the script from the same folder as the dlls yields success. I had only tried running vspipe from the dll folder prior to this.
Mystery Keeper
5th August 2014, 14:17
The most simple solution is to add dlls folder to PATH environment variable.
Myrsloik
6th August 2014, 23:41
I've added a second test version that's compiled for 64 bits (link in the first post). Nodame worked long and hard and managed to make it a single dll so the dllpath argument isn't needed anymore.
Report on your success/failures with unicode filenames.
This plugin will be added to the main source tree once it's working well enough.
LoRd_MuldeR
7th August 2014, 01:28
Well, I can't even get past LoadPlugin because of missing dlls even when they are in the same directory as imwri.dll.Running the script from the same folder as the dlls yields success. I had only tried running vspipe from the dll folder prior to this.
Keep in mind that Windows only looks for DLL's in the same folder where the main EXE file is located. But if some DLL depends on additional DLL's, it will not necessarily look in the folder where the DLL is located.
For example, if some EXE file explicitly loads a plug-in DLL from a certain "plug-ins" directory that differs from the directory where the EXE file itself is located and if that plug-in DLL depends on yet another DLL, then Windows will not look in the "plug-ins" directory for that other DLL (as one might expect) - it still only looks in the folder where the main EXE resides!
If the required DLL could not be found in the directory where the EXE file is located, Windows falls back to certain system directories (C:\Windows\System32, C:\Windows, etc). Then to the directories contained in the PATH environment variable. And finally it falls back to the "current" directory. So that's probably why "running the script from the same folder as the dlls" worked, because that happened to be your "current" directory then.
Myrsloik
7th August 2014, 11:41
First post once again updated with an improved version. Nodame managed to add in support for even more formats in the static builds and now both versions are a single simple dll.
The dllpath argument is dead!
So start testing. This should work and only be a minimal hassle to use now.
alexxdls
12th August 2014, 07:01
Can this plugin read image sequence? I've tried ext = '.png'
dir = r"F:\TEMP\50-SHADES_TRL-A_RU-XX_RU_51_1080P_UP_20140725_MPS_IOP_OV\REEL1/"
srcs = [dir + src for src in os.listdir(dir) if src.endswith(ext)]
v1 = core.imwri.Read(srcs)like with previoous ImageReader, but it now outputs only the first image and all frames are equal. Checking the script givesScript was successfully evaluated. Output video info:
Frames: 341 | Time: 0:00:14.208 | Size: 1920x1080 | FPS: 24/1 = 24 | Format: YUV444P10
Myrsloik
12th August 2014, 07:52
Can this plugin read image sequence? I've tried ext = '.png'
dir = r"F:\TEMP\50-SHADES_TRL-A_RU-XX_RU_51_1080P_UP_20140725_MPS_IOP_OV\REEL1/"
srcs = [dir + src for src in os.listdir(dir) if src.endswith(ext)]
v1 = core.imwri.Read(srcs)like with previoous ImageReader, but it now outputs only the first image and all frames are equal. Checking the script givesScript was successfully evaluated. Output video info:
Frames: 341 | Time: 0:00:14.208 | Size: 1920x1080 | FPS: 24/1 = 24 | Format: YUV444P10
Found the typo in the code. Will post a fixed version in a bit.
kolak
12th August 2014, 21:25
Does it read fps from DPX header?
Does read support same % mode as write, eg.
test_%03d.tiff for test_001, test_002, test_003,..... image sequence?
Myrsloik
12th August 2014, 21:26
Does it read fps from DPX header?
No, not yet at least.
kolak
12th August 2014, 21:30
What format are files decoded to, x bit RGB?
Myrsloik
12th August 2014, 21:36
IMPORTANT ANNOUNCEMENT
The test2 archive has been updated. It now handles reading lists of files properly. Before it would simply return the first image over and over again due to a typo. Get it from the first post.
What format are files decoded to, x bit RGB?
Only 8-16 bit rgb for now. Going to try to add proper grayscale and yuv in a bit. Returning original subsampled data (such as 420 jpeg) is probably impossible with imagemagick.
kolak
12th August 2014, 21:50
RGB is good in this case, I assume.
Wilbert
12th August 2014, 21:55
Returning original subsampled data (such as 420 jpeg) is probably impossible with imagemagick.
I never implemented this in Immaavs, but i always thought that this would be possible. Please let us know if that's not the case.
Myrsloik
13th August 2014, 00:08
Now I've encountered another problem. I have no test images that are identified as being in a yuv-ish colorspace so I can't add support for reading them. Apparently jpeg images aren't considered yuv.
My own web hunt for this kind of image failed so sample images are requested.
foxyshadis
13th August 2014, 00:41
I never implemented this in Immaavs, but i always thought that this would be possible. Please let us know if that's not the case.
I did see that thread you made (http://www.imagemagick.org/discourse-server/viewtopic.php?f=2&t=14645), but I see your last question was never answered. You'd have to mod coders/jpeg.c to change:
i=(ssize_t) jpeg_read_header(&jpeg_info,TRUE);
if ((image_info->colorspace == YCbCrColorspace) ||
(image_info->colorspace == Rec601YCbCrColorspace) ||
(image_info->colorspace == Rec709YCbCrColorspace))
jpeg_info.out_color_space=JCS_YCbCr;
to:
i=(ssize_t) jpeg_read_header(&jpeg_info,TRUE);
if (image_info->colorspace == UndefinedColorspace)
jpeg_info.out_color_space=jpeg_info.jpeg_color_space;
else if ((image_info->colorspace == YCbCrColorspace) ||
(image_info->colorspace == Rec601YCbCrColorspace) ||
(image_info->colorspace == Rec709YCbCrColorspace))
jpeg_info.out_color_space=JCS_YCbCr;
and then rebuild. Or just use your own code to detect it ahead of time.
There is a flag that IM doesn't use, jpeg_info.raw_data_out, that will give you non-upsampled pixels. Without it they're always upsampled with a bilinear filter. You'd have to write a bit of code to trick IM into working, since its routines won't work; you have to use jpeg_read_raw_data() instead of jpeg_read_scanlines() and fill the RGB buffers as you wish.
(I forgot how much of a migraine reading IM's source gives me.)
foxyshadis
13th August 2014, 00:42
Now I've encountered another problem. I have no test images that are identified as being in a yuv-ish colorspace so I can't add support for reading them. Apparently jpeg images aren't considered yuv.
My own web hunt for this kind of image failed so sample images are requested.
Practically all JPEG images are YCbCr. (Rec.601 fullscale, to be exact.) IM just doesn't report them as such, since it converts them to RGB normally, though it also supports CMYK and Lab.
alexxdls
13th August 2014, 03:19
IMPORTANT ANNOUNCEMENT
The test2 archive has been updated. It now handles reading lists of files properly. Before it would simply return the first image over and over again due to a typo. Get it from the first post..Thanks. It works fine now. But could you give a look on my report about VapourSynth here https://www.doom9.org/showpost.php?p=1689749&postcount=1339 and here https://www.doom9.org/showpost.php?p=1689811&postcount=1341
Please
And just one note moreimport vapoursynth as vs
core = vs.get_core()
import os
core.std.LoadPlugin(path=r"d:\TOOLS\MyDCPConverter\Tools\imwri-64.dll")
core.std.LoadPlugin(path=r"d:\TOOLS\MyDCPConverter\Tools\fmtconv.dll")
vl = core.imwri.Read(r"F:\TEMP\TRAIN-DRAGON-2_TLR-G-3D_RU-XX_RU-00_51_2K_TCF_20140417_DWA_IOP-3D\REEL2\000034L.png")
vr = core.imwri.Read(r"F:\TEMP\TRAIN-DRAGON-2_TLR-G-3D_RU-XX_RU-00_51_2K_TCF_20140417_DWA_IOP-3D\REEL2\000034R.png")
v = core.std.StackHorizontal([vl,vr])
v.set_output()
Withvr = vlthe script goes well, but withvr = core.imwri.Read(r"F:\TEMP\TRAIN-DRAGON-2_TLR-G-3D_RU-XX_RU-00_51_2K_TCF_20140417_DWA_IOP-3D\REEL2\000034L.png")doesn't, again. But now vr equals vl. What is the difference?
It seems like I can't output video with two different imwri.Read's, doesn't it?
Myrsloik
13th August 2014, 13:32
It actually appears to be because of how imagemagick was compiled when creating a single file plugin. The error message actually comes from pthreads. I'm trying to think of how to fix it.
Anyway, next update will have grayscale support.
kolak
17th August 2014, 18:58
How do I load image sequence?
I've tried test_%03d.tif, but it did not work.
Loading single files was fine.
Myrsloik
17th August 2014, 19:00
How do I load image sequence?
I've tried test_%03d.tif, but it did not work.
Loading single files was fine.
That's how you do it. Are the files named test_000.tif, test_001.tif...?
kolak
17th August 2014, 19:12
Yes. It says that files can't be found. Does it have to start with 0?
Myrsloik
17th August 2014, 19:13
Yes. It says that files can't be found.
Try using the full path. And yes, it has to start at 0 at the moment.
kolak
17th August 2014, 19:24
This is probably the reason. Mine starts from 1. Can we have start number as a variable?
Myrsloik
17th August 2014, 19:30
This is probably the reason. Mine starts from 1. Can we have start number as a variable?
Yes, I'll add it for the next test version.
kolak
17th August 2014, 19:37
How does the writer work.
I tried
s=source...
core.imwri.Write(s, 'DPX', 'D:\test_%03d.dpx')
And put script through vspipe.
Nothing written to the disk. Script itself givses correct output.
jackoneill
18th August 2014, 00:51
How does the writer work.
I tried
s=source...
core.imwri.Write(s, 'DPX', 'D:\test_%03d.dpx')
And put script through vspipe.
Nothing written to the disk. Script itself givses correct output.
s = source
s = core.imwri.Write(s, ...)
s.set_output()
Frames that aren't requested from imwri.Write() aren't written.
kolak
18th August 2014, 08:15
Thank you.
I figured it out.
alexxdls
18th August 2014, 14:30
How do I load image sequence?
I've tried test_%03d.tif, but it did not work.
Loading single files was fine.dir = r"dir\path/"
srcs = [dir + src for src in os.listdir(dir)]
v = core.imwri.Read(srcs)works fine for loading images from directory
kolak
18th August 2014, 14:44
%xd also works, but only when your first image has number 0.
When I tried your method I had error saying:
"Don't know what os means".
sneaker_ger
18th August 2014, 19:54
You need "import os" at the top of your script.
kolak
21st August 2014, 13:10
Thx.
Will try.
alexxdls
23rd August 2014, 04:00
Any update in near future?
Myrsloik
24th August 2014, 01:16
Any update in near future?
Maybe in a day or two when I finish all the big changes. I decided to go back and redo a fairly big amount of code because the C++ api is useless.
alexxdls
24th August 2014, 05:51
Maybe in a day or two when I finish all the big changes. I decided to go back and redo a fairly big amount of code because the C++ api is useless.Thanks. I hope you will be able to solve an issue with stacking two different image seqeunces.
Myrsloik
24th August 2014, 18:11
Third test and a small list of notable changes in the first post. The dllpath argument is back and so is the dll mess. I'll probably get around to making a single file dll compile some day with mingw. But that's complicated.
This should more or less be the final version. ImageMagick as a library is simply too abstracted/awkward/horrible to use to return native colorspaces. On the positive side I think it can do most important things, read and write a big pile of formats as image sequences. If I ever locate a better library to use maybe I'll have another go. And remember that ffms2 also works for image reading if you want to try something else.
alexxdls
25th August 2014, 03:08
And remember that ffms2 also works for image reading if you want to try something else.I dubt it supports high bit depth images...
kolak
25th August 2014, 12:35
It does, as it's based on ffmpeg.
vcmohan
27th October 2014, 12:29
! am confused. I tried to load the imwri.dll from test3.
It gave a message cannot load plugin
Should I use test 2 plugin? I am using 32 bit only.
Reel.Deel
6th November 2014, 03:06
@Myrsloik
Any possibility of a single plugin for r25?
Myrsloik
6th November 2014, 10:34
@Myrsloik
Any possibility of a single plugin for r25?
I at least have one workaround in mind so dllpath won't be needed anymore now that plugins can get their own path in r25. No idea if my mingw skills will be enough to slap it into single file submission though. But I'll try. Higher on the list is alpha support in FFMS2 though. Poor linux users can have no alpha...
Myrsloik
25th November 2014, 16:54
Posted test4 in both 32 and 64 bit versions. This one removes dllpath and needs vs R25. In combination with vs R25 it can easily be loaded with loadplugin or autoloaded (if you dump that huge lump of files into the autoload directory, not recommended but it should work).
It also has a slightly newer imagemagick but with ffmpeg.exe removed (don't try to read mpeg files it). Try it and see what happens. Apart from being usable there are no other improvements since I don't feel like making my own imagemagick distribution.
MonoS
21st December 2014, 00:16
I get this error using VapourSynth Editor
vapoursynth.Error: Read: Failed to read image properties: vsedit-32bit.exe: RegistryKeyLookupFailed `CoderModulesPath' @ error/module.c/GetMagickModulePath/662
The script is this one
import vapoursynth as vs
core = vs.get_core()
core.std.LoadPlugin("C:/Program Files (x86)/VapourSynth/plugins32/imwri/imwri.dll")
src = core.imwri.Read('C:/Users/MonoS/Desktop/Personale/B2wAZhvIgAEraOP.png')
src.set_output()
Myrsloik
21st December 2014, 00:22
I get this error using VapourSynth Editor
...
Does that happen with all image files or just that one? Does it work outside the editor?
MonoS
21st December 2014, 17:12
Nothing, tried using vspipe and changing file, but nothing, still the same error
18fps
23rd December 2014, 15:05
I dubt it supports high bit depth images...
What it does not supports is image sequences, only single images.
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.