I need to take a BMP that I have in memory (stored as an HBITMAP or a CImage take your pick), and save it to a PNG file on disk.
Here is how I am currently saving the image as a png.
CImage img;
img.Save("foo.png")
My problem is that is far too slow (250ms for ~1920X1080). This takes 3X the time of saving as JPG, and about 9X the time of saving as a BMP.
I know there are a lot of g++ libraries for linux (e.g. libpng) that will do this, but most of the libraries that support visual studio only support version 6, and I haven't found one with benchmarks, so I'm kind of hesitant to try getting these libraries working only to find out they are too slow.
I am not sure what type of encoder windows uses (it's hidden in a DLL), but there must be a faster one (I'm even willing to sacrifice a bit of disk size, up to twice as much).
Java libraries do this very quickly, but for some reason Microsoft's library is slow as a turtle.
So I was wondering what options I have for saving screen-sizes PNGs to disk in ~100ms?
I'd bet (but I have no bencharks) that libpng is the best option.
At least, I'd seek a library that allows to tune the saving options ( CImage doesn't). There are two relevant options to try:
Zlib compression level (0-9) : the typical default value (6) is usually ok, you'll rarely gain much speed using less compression
Filter type. This can be more important. If we want to optimize for speed, I'd preselect a unique filter (usually PNG_FILTER_PAETH).
It's very easy to compile libpng yourself. I just did it myself before typing this resposne out. It took about 90 seconds.
Download zlib from http://zlib.net/ Either in source or precompiled form such that you have zlib.h
Download libpng from http://sourceforge.net/projects/libpng/files/libpng15/1.5.12/lpng1512.zip/download
Unzip the contents of libpng zip file.
Open a command shell.
"cd /d d:\projects\libpng" (cd into whatever directory you just unzipped the libpng sources from)
"copy scripts\libpng.h.prebuilt libpng.h"
Create a new Visual Studio C++ project (static library) in the libpng directory
Add all the *.c files from the libpng directory to the project
Add your zlib project directory to the project's include path. (Wherever it can find zlib.h)
Build your project. It should compile the png code library just fine. Done.
Related
I'm trying to write a program in C++ to write static arrays and matrices to .mat files so that I can load them into Matlab, and I'd also like to be able to read them. I've done a lot of reading and I'm aware that there's some framework I need to properly set up in XCode in order for things to work. I'm using Matlab R2015b and Xcode 7.3.
I'm modeling my code initially to be simple like what the author mentions in Reading data from matlab files into C but I can't locate my libraries. The folder /glnxa64/ does not exist on my machine. I know that my headers I want to include are in applications/MatlabR2015/extern/include for mat.h, matrix.h.
I have two problems: Under my project settings in XCode, what do I modify to make sure my project finds mat.h and matrix.h, is it under the "Precompiled Headers Cache Path" or elsewhere? Also, where do I find those library files and how do I link them in XCode, is it just under the Project Build Phase link binary with libraries?
Thanks for the help!
I found the solution to the second part of my question. The first part was just me messing with the project build settings instead of the target build settings.
The folder for the libraries that Matlab has depends on what operating system and version of Matlab you're on. Opening matlabR2015b.app by making the finder show package contents, then navigating to applications/MatlabR2015b.app/bin/maci64/ is where the library binaries are located on my machine. The name maci64 changes depending on the OS (since I'm on a mac 64-bit OS, I believe that's where my path name came from) and manually paging through the list of libraries found it, since using the file search doesn't really work inside a package.
My code still won't compile because it looks like I need to include all of the right codependent libraries, and I don't know which other ones I need (I only included libmex.dylib and libmat.dylib), but I found where the libraries are stored.
I'm totally new in using Qt and I don't know a lot of stuff.
As a test I created a simple application using Visual Studio 2012 and Qt-VS-Add-in based on the newest Qt5.1
After I compiled the application it didn't work for me (gave errors), I searched all over the internet and found a lot of people saying that I have to copy those dlls mentioned below from the directory:
C:\Qt\Qt5.1.0\5.1.0\msvc2012\bin\
DLL's I had to copy to make my application work:
icudt51.dll
icuin51.dll
icuuc51.dll
libEGL.dll
libGLESv2.dll
Qt5Core.dll
Qt5Gui.dll
Qt5Widgets.dll
My problem is the size of these dlls, they're about "37 MB" and my application itself is only "30 KB"! So, those Qt libraries will add at least 37 MB to my application [ Which I don't see it happens with other Qt-based applications I download ]. Is there any solution can make me end up with a single small .exe file?!
And I heard some people saying that I have to also include a dll for Microsoft C++ Compiler, can you explain this for me?
Note: I've come across a lot of questions here on StackOverFlow but I couldn't find anything can help me, so please do not flag this as a duplication because if I found a clear answer I wouldn't post this question!
Any help would be appreciated.
UPDATE: Use windeployqt.exe! It works really well.
http://doc.qt.io/qt-5/windows-deployment.html#the-windows-deployment-tool
The simplest way to use windeployqt is to add the bin directory of
your Qt installation (e.g. ) to the PATH variable and then
run:
windeployqt <path-to-app-binary>
UPDATE: Upon Further testing, windeployqt did not copy over all the MingW dlls for me. (Tested with Qt 5.4 on Windows 10 with MingW 4.9.1). So you need to manually get the last 3 dlls before deploying:
libgcc_s_dw2-1.dll
libstdc++-6.dll
libwinpthread-1.dll
From
C:\Qt\5.4\mingw491_32\bin
I think you may have a few extras in your list... I would double check the docs in the links below...
Here is the definitive documentation on it:
http://doc.qt.io/qt-5/windows-deployment.html
http://doc.qt.io/qt-5/windows-deployment.html#application-dependencies
Size of Qt DLLs
The amazing Qt Libraries can do a lot, but they are kind of big. Some of the older versions of Qt might be a little smaller.
For Qt 4.8 msvc QtCore4.dll is 2.5 MB, and QtGui4.dll is 8.4 MB.
How Windows Resolves Shared Libraries/Dynamic Link Libraries (DLL)
Here is how Windows tracks down a library at runtime:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx
Single Small EXE
If you statically link, then your EXE should grab the libraries it needs and gets built into a stand alone exe. It still may be dependent on msvc redistributables. See the next section for more info on it. But it now compiles down the .libs that you reference into your EXE and your exe no longer is pointing at other dynamically linked libraries. It does take more time to get your statically linked exe environment setup.
Your exe will certainly get bigger as it now includes the binary information for the libraries that you referenced before.
https://www.google.com/search?q=qt+static+linking
EDIT:
Statically building the exe, means that you aren't using the LGPL version.
means that you have to have your object files easy to access to end users if you are using LGPL.
I think #peppe described it well (see comment below):
Technically, you are allowed to statically link when using Qt under LGPL, even if your application is not using LGPL. The only tricky requirement is keeping the ability for a third party to relink your application against a different Qt version. But you can comply with that easily, f.i. by providing a huge object file (.o) of your application, that only needs to be linked against any Qt version.
http://blog.qt.io/blog/2009/11/30/qt-making-the-right-licensing-decision/
Look at the chart near the bottom. If you are doing the commercial version, then you can statically link, without worrying about the object files.
MSVC Redistributables
Redistributable dependencies have to do with the run-time library linker options.
http://msdn.microsoft.com/en-us/library/aa278396(v=vs.60).aspx
/MD, /ML, /MT, /LD (Use Run-Time Library)
To find these options in the development environment, click Settings on the Project menu. Then click the C/C++ tab, and click Code Generation in the Category box. See the Use Run-Time Library drop-down box.
These two links below talk about some older versions of visual studio, but the reasoning should still stand.
http://www.davidlenihan.com/2008/01/choosing_the_correct_cc_runtim.html
How do I make a fully statically linked .exe with Visual Studio Express 2005?
Hope that helps.
Just open your terminal execute your_qt_installpath/version/compiler/bin/windeployqt.exe YourApplication.exe. It will automatically copy all the required libs and stuff into the folder, where your exe is located and you can just distribute it.
For Windows you need to include qminimal.dll and qwindows.dll, you will have to put them in folder called platforms.
Even if you program is small you still call huge libraries to do the graphical interface. If the size is really important you should do a console project.
PS : You can check all the libraries you really need by opening your exe with the dependency walker.
I found another workaround without recompiling Qt again!
[ This solution may affect application execution time ]
First we need to use UPX to compress each one of Qt Libraries required by our application, they're often the dll's mentioned in the question. However, avoid compressing them too much because you'll notice that your application takes longer time to run.
[ Optional ]: If your application binary is large, you may find it useful to compress it using UPX.
After compressing all binaries, we want to get a single .exe file, so we can use
Enigma Virtual Box [ http://enigmaprotector.com/en/downloads.html ] to merge all .dll files with the main executable and we'll end up with a single tiny .exe file!
I'll just do it like this for now since I'm not able to recompile Qt with my own configurations on my current machine.
it looks to me that Qt5.2 requires fewer dll.
Qt5Core.dll
Qt5Gui.dll
Qt5Widgets.dll
in windows you also need "qwindows.dll" in folder "platforms".
give it a try.
A possibility for reducing the size of the DLLs is by compressing them with UPX as mentioned by Alaa Alrufaie. Another method is to wrap it into an installer (e.g. Inno Setup). The latter one is particularly useful if you want to distribute it to end users). I had a simple application requiring Qt5Core.dll, Qt5Gui.dll, Qt5Widgets.dll and qwindows.dll (in the folder "platforms") taking about 17 MB. After creating a setup file, it shrank to 5 MB.
Continuation of:
Standalone Cross Platform (Windows/Linux)) File Compression for C/C++?
After many attempts on ZLIB ZZLIB LIBZIP MINIZIP I always get many problems at the compilation stage. Many google searches turned out OS-specific libraries and I can't really find anything that fit my 'simple' needs.
I reduced my needs for the library (Or wrapper?) to this:
Works on both Windows and Linux OR 2 separate libraries; one which works on Windows and the other one on Linux, I can make 2 separate projects for Windows and Linux if it is really neccesary
Unpack file from zip to specified directory
Check if file exists in zip file
C OR C++ OR Mixed (yeah, that doesn't matter)
Preferably Very Simple to include into any project
(eg 5 c/cpp files and 1-3 header files? anyway not tons files, when I open all the libzip and zlib archives I have something like: "O my ..")
I've checked many stackoveflow threads too with the words "Windows Linux ZIP C C++" but all the results seem so have libraries which I OR don't know how to compile OR is too difficult to use OR it has too many 'needed stuff' for just simple zip extract and check if file exists.
I had put that project away for a later date and begun it now, and all those compilation errors came up (especially that VC++2010 doesn't have the C-99 inttypes.h)
I have had very good experience with Zipstream C++ library which gives you a nice OOP way of handling zip files.
If your project already uses some of the bigger libs like Boost , then you could try to use the boost::iostreams with the gzip filter, however the functionality is somehow limited.
Or if you happen to use Poco take a look at they're implementation Poco::Zip
I have some C++ code which uses boost's GIL image library, and wants to write files using boost::gil::png_write_view from boost/gil/extension/io/png_io.hpp. That header itself includes png.h, and of course results on a link dependency.
On Debian it compiles and links fine. If it did complain about anything missing, the necessary headers and libs would be a few seconds away via an aptitude install libpng-dev.
On Windows (VisualStudio 2008 on XP64), I'm having to face the idea that it looks like I'll have to build libpng from source (and so also its zlib dependency) myself. If there's an obvious packaging already out there, I'm not seeing it. Can anyone enlighten me if there is such a useful resource anywhere ?
Libpng's own packaging itself seems to supply project files for vc6 and VC7.1 (VS2003). And more recent releases also come with VC10 project files. But nothing for VC8(VS2005) or VC9(VS2008). However there are instructions here (which I've yet to try) which describe building for 2008 after running the 7.1 project files through the conversion wizard.
I did initally try the GnuWin32 build of libpng, but (apart from being 32 bit only) it crashed in a libpng call to fwrite when passed a FILE* from VS2008's CRT. libpng's own documentation has something to say about this and the perils of mixing different versions of MSVC but their suggested workround is only relevant to direct libpng users (and I'm using it via boost GIL).
Update: the converted project files do work pretty well (maybe some minor obvious fixups). By far the biggest part of the job was creating the 64bit builds; the original and converted project files don't include any such configuration and while visual studio will have a go at creating them, there was a fair amount of config dialog editing to get consistent folder/file names etc.
I'm trying to get my webcam to capture video in OpenCV, version 2.2 in Windows 7 64 bit. However, I'm having some difficulties. None of the sample binaries that come with OpenCV can detect my webcam. Recently I came across this posting which suggested that the answer lies in recompiling a file, opencv_highgui with the property HAVE_VIDEOINPUT HAVE_DSHOW in the property page.
Can't access webcam with OpenCV
However, I'm unsure about procedurally how to do this. Can someone recommend as to how to go about this? Thanks.
Roughly, these are the important steps:
Download the OpenCV 2.2 source code,
set up a project to compile it, according to the InstallGuide,
make any changes you need to make in the code,
build the opencv_highgui library (dll and lib files, probably), and
replace these in your original project.
If you can configure the project to generate the highgui files only (and not every library in OpenCV), do so, since the change you need to do shouldn't affect other modules. This saves some time.
The detailed instructions to build OpenCV are in: http://opencv.willowgarage.com/wiki/InstallGuide. You should follow this guide.