Using OpenGL to write to an image file - c++

I'm just curious if there is a way to use OpenGL to write pixel data to an external JPEG/PNG/some other image file type (and also create an image to write the data to if one does not already exist). I couldn't really find anything on the subject. My program doesn't really make use of openGL at all otherwise, I just need something that can write out images.

Every image "put into" or "taken from" OpenGL is in a rather raw pixel format. OpenGL does neither have functionality for file I/O nor for handling of sophisticated image formats like e.g. BMP, JPEG or PNG, as that is completely out of its scope. So you will have to look for a different library to manage that and if this was the only reason you considered OpenGL, then you don't need it at all.
A very simple and easy to use one (and with an interface similar to OpenGL) would be DevIL. But many other larger frameworks for more complex tasks, like Qt (GUI and OS) or OpenCV (image processing) have functionality for image loading and saving. And last but not least many of the individual formats, like JPEG or PNG usually also have small official open-source libraries for handling their respective files.

Related

Most efficient way to store video data

In order to accomplish some specific editing on some .avi files, I'd like to create an application (in C++) that is able to load, edit, and save those .avi files. But, what is the most efficient way? When first thinking about it, a simple 3D-Array containing a 2D-array of pixels for every frame seems the simplest solution; But then its size would be ENORMOUS. I mean, let's assume that a pixel only needs a color. One color would mean 3bytes (1char r, 1char b, 1char g). If I now have a 1920x1080 video format, this would mean 2MEGABYTES for only one frame! This data may or may not be smaller if using pointers for the colors, so that alreay used colors wont take more size - I don't really know, since I'm pretty new to C++ and the whole low-level stuff. (As a comparison: One of my AVI files recorded with Xvid codec is 40seconds long, 30fps, and only has 2MB.)
So how would you actually store the video data (Not even the audio, just the video) efficiently (while still being easily able to perform per-frame-changes on it)?
As you have realised, uncompressed video is enormous and it is not practical to store an entire video in this way.
Video compression is an extremely complex topic, but more-or-less, it works as follows: certain "key-frames" are compressed using fairly standard compression techniques similar or identical to still-photo compression such as JPEG. Frames following key-frames are compressed by comparing the frame with the previous one and looking for changes (such as moving blocks). Every now and again, a new key-frame is used.
You don't really have to worry much about that as you are not going to write your own video coder/decoder (codec). There are standard ones.
What will happen is that your program will decode the compressed video frame-by-frame and keep a certain number of frames in memory while you are working on them and then re-encode them when it is finished. In the uncompressed form, you will have access to the individual pixels and can work on them how you want.
You are probably not going to do that either by yourself - it is very hard. You probably need to use a framework, such as OpenCV. There are a huge number of standard filters and tools built in to these frameworks, and it may be that what you want to do is already implemented somewhere.
The OpenCV framework can return individual frames in a Mat object and you can then access the pixels. See this post Get Pixels from Mat
OpenCV
Tutorial page: Open CV Tutorial

Qt 5 dds support to save memory and improve rendering

I would like to load dds files into Qt 5.1 and have the benefit of saving memory and improve rendering performance as dds files in many cases are less in size (due to data destroying compression) than their png equivalent and also are stored in more cache friendly rendering structure "tiling" (i.e. http://fgiesen.wordpress.com/2011/01/17/texture-tiling-and-swizzling/) than usual raw image data is.
But... I can't find any reference about this topic when googling I only find others who read dds files and convert them into QImage which I suspect only unpacks the dds into a raw rgba only giving some extra performance when reading from disk but keeping all the bad parts like more memory, less efficient texel reading and now also compression artifacts for nothing.
Have I missunderstood how Qt is handling textures or can the dds formats dxt1-5 be utilized corretly within Qt 5.1?
Does the QImageReader "unpack" dds files to raw or actually loads them directly to graphics hardware as is?
Any other suggestions or pointers is very appreciated.
QImage is a pure software object, it does not store anything on the graphics card and it has no support for exotic internal data ordering. The internal formats that QImage support are listed here: https://doc.qt.io/qt-5/qimage.html#Format-enum
So you basically have no other option of getting the data into a QImage than unpacking everything and flattening it out.
QPixmap supports reading from a file directly, see https://doc.qt.io/qt-5/qpixmap.html#load
Unlike QImage, QPixmap is an object that stores its data on the graphics card. It would be theoretically possible to do what you envision given the Qt interface. However my educated guess is that Qt still does not support this at all.

Save a raw image in OpenCV

I'm trying to use OpenCV to read/write images for me. Currently, I have them in a different, non-standard format, and I know how to get them into OpenCV's containers. Here are the requirements:
The pixels are 1, or 3 bands, U8, U16, U32, or F32
The images have metadata, random stuff, like the camera ID that took the images. I would like the metadata to be vi/notepad editable
I want to write as little code as possible when it comes to low level stuff. My experience is that this stuff requires the most maintenance.
I can define the format. It's only to read and write for these programs.
I don't want the pixels to be anything but binary, '0.5873499082' is way too much data for one float.
Is there a way to describe to OpenCV how to read and write image types it doesn't know? Are there image types already available for the types of images I have?
My interim solution is to use boost to serialize the image, and save the metadata in a separate file.
Try using gdal library for reading images and then convert it to IplImage.
OpenCV can't do that for you, you can store the metadata in a separate file, or you can use for example the jpeg exif (that won't be notepad editable though).

Simple image analysis

I am looking for a method, software or library for simple image analysis.
The input image will be a white-colored background, and some random small black dots on it.
I need to generate a .txt file that represents these dots' coordinates. That is, if there are three dots in the image the output will be a text file that includes somehow a representation of three coordinates, (x1,y1), (x2,y2), and (x3,y3).
I have searched the web for hours and didn't find something appropriate, all I found was complex programs for image processing.
I've been told that it's easy to write code for this mission in MATLAB, but I'm unfamiliar with MATLAB.
Can this be done easily with C++, Java or C#?
Any good libraries?
It is quite simple in any language. Depending on the form of your input, you probably need to go over all of it (assuming it is a simple matrix - simply have two nested loops, one for the x coordinate and one for the y coordinate), whenever you encounter a black dot - simply output the current indexes which would be the x and y coordinates for the dot.
As to libraries, anything other than something to decode your input to the form of such a matrix (e.g. a JPEG decoder) would be overkill.
I don't think you would need image processing libraries for this kind of problem (somebody correct me if I am wrong) since these libraries may focus on image manipulation and not recognition. What you will need is a knowledge of the image format that you are supporting (how are they stored, how are they interpreted, etc) and basic C file system functions.
For example, if you are expecting a JPG file format you will simply calculate the padding for each scanline and reach each scan line one by one, and each pixel in the line one by one. You'd have to use two counters, one for the row and one for the column. If the pixel is simply not white, then you have your coordinate
This is something which should be very easy for you to do without any external software; something like
for(y in [0..height]) {
for(x in [0..width]) {
if(pixels[y][x].color == BLACK)
print("(%d, %d)", x, y);
}
}
would work.
The bitmap file format is quite easy to read.
http://en.wikipedia.org/wiki/BMP_file_format
You could just stream the bytes into an array using this info. I've written a few BMP readers; it is a trivial matter.
Also, although I cannot vouch for its ease of use as I've never used it before, I've heard that EasyBMP works fine too.
CImg library shold help you. From CImg FAQ:
1.1. What is the CImg Library ?
The CImg Library is an open-source C++ toolkit for image processing.
It mainly consists in a (big) single header file CImg.h providing a
set of C++ classes and functions that can be used in your own sources,
to load/save, manage/process and display generic images. It's actually
a very simple and pleasant toolkit for coding image processing stuffs
in C++ : Just include the header file CImg.h, and you are ready to
handle images in your C++ programs.

Loading PNG textures to OpenGL

I'm working on a game, and all of my graphics use magenta as transparent/magic color.
They are all 32-bit and the magenta is just for conveniency.
Anyway, I would appreciate if someone could advice me what library should I use to load my images (I need to load them in GL_RGBA format, both internal and texture specific).
If only PNG support is necessary, use libpng. DevIL is supposed to be easy, but it's somewhat bloated (does a lot more than just load images) and internally actually calls OpenGL functions which can mess with your own OpenGL logic.
I personally prefer SDL_image, since I'm using SDL in my projects anyway. While not immediately obvious, SDL_BlitSurface() function can do the conversion from whatever IMG_Load() returns to the necessary pixel format.
DevIL can load virtually every file format and can directly create OpenGL textures. It is the easiest way to go.
You should also use a file format which supports an alpha channel (PNG, TGA, ...). Using a "magic color" in 32-bit images is really out-dated!
Apart from the other answers mentioning SDL and DevIL, there are two more options to consider:
Use libpng directly. This will probably have the smallest impact on the code size if that matters, since you get no bloat for other formats you're not using, no DLLs, etc.
Use operating-system texture loading. This can be a nice way to reduce dependencies if you prefer using OS features over external libraries. GDI+ in Windows XP and up has built-in texture loading for a few formats like PNG and JPEG, and I don't know for certain, but other OSs might have similar features. It's pretty simple to hook GDI+ up in to OpenGL and then the OS is taking care of your texture loading!
There is a very minimalist one file example of loading a png into openGL here:
http://tfc.duke.free.fr/coding/src/png.c
Another option is OpenCV.
It does a lot more than just texture loading, but odds are good you'll find use of its other features as well.