I'm looking for a simple c/c++ lib that would allow to extract the first frame of a video as a uchar array. And have a simple fonction to access the next one.
I know of FFMPEG but it requiere to play with packet and things like that, and i'm surprised that nowhere on the net i can find a lib that allow something like :
Video v = openVideo("path");
uchar* data = v.getFrame();
v.nextFrame();
I just need to extract frames of a video to use it as a texture...no need for reencoding after or anything...
of course something that would read the most format than possible would be great, something built upon libavcodec for example ;p
And i'm using Windows 7
Thanks!
Here's an example with OpenCV:
#include <cv.h>
#include <highgui.h>
int
main(int argc, char **argv)
{
cv::VideoCapture capture(argv[1]);
if (capture.grab())
{
cv::Mat_<char> frame;
capture.retrieve(frame);
//
// Convert to your byte array here
//
}
return 0;
}
It's untested, but I cannibalized it from some existing working code, so it shouldn't take you long to get it working.
The cv::Mat_<unsigned char> is essentially a byte array. If you really need something that's explicitly of type unsigned char *, then you can malloc space of the appropriate size and iterate over the matrix using
You can convert a cv::Mat to a byte array using pixel positions(cv::Mat_::at()) or iterators (cv::Mat_::begin() and friends).
There are many reasons why libraries rarely expose image data as a simple pointer, such as:
It implies the entire image must occupy a contiguous space in memory. This is a big deal when dealing with large images
It requires committing a certain ordering of the data (pixel vs non-planar -- are the RGB planes stored interspersed or separately?) and reduces flexibility
Dereferencing pointers is a cause for bugs (buffer overruns, etc).
So if you want your pointer, you have to do a bit of work for it.
You can use OpenCV it is very simple and they have a useful manual on their site http://opencv.willowgarage.com/wiki/
Use DirectShow. Here's an article: http://www.codeproject.com/KB/audio-video/framegrabber.aspx
There are DirectShow 'add-ons' to decode different video formats. Here's one of the sites where you can grab free DirectShow filter packs to decode some common formats that are not directly supported by DirectShow: http://www.free-codecs.com/download/DirectShow_FilterPack.htm
Related
I have a program that grabs an image using BitBlt() and is stored in a variable unsigned char* image. Ideally before uploading it to my server I would like to compress it since it's somewhat large uncompressed. I've tried a couple different ways with zlib, writing my own run length encoding method, and more but no luck. I chalk it up to me not having a strong understanding compression.
I searched and found some examples using zlib but my image appears to stay the same size after attempting to compress it. Here is that code:
unsigned char* compressBitmap(size_t inImgSize, unsigned char* inImage)
{
uLongf srcLen = inImgSize;
uLongf destLen = compressBound(srcLen);
unsigned char* outImage = new unsigned char[destLen];
int res = compress((Bytef*)outImage, &destLen, (Bytef*)inImage, srcLen);
return outImage;
}
I checked and confirmed it is not returning an error. Everything is executed and the image makes it to the server fine, just not compressed at all. I am probably making a bunch of dumb mistakes so any help is appreciated.
Lossless compression on image data doesn't usually lend itself to reduced file sizes (especially photos, simple icons maybe). If you want to know whether the compression is actually working, try uploading an entirely black image and see if the size reduces. If you can see a reduction in file size on a black image, but not the images you are using, you may have to consider using a lossy format instead (e.g. jpeg, png, etc).
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
I have a byte array named pBuffe of type unsigned char* pBuffer that was fed an 'image' (a bunch of bytes) by a high powered camera after it captured a picture. How do I go about converting this byte array into a viewable bitmap image file?
I think you can solve this easily by using the well-known and popular EasyBMP library. It creates the proper file header and everything you need for it. As a bonus, it supports multiple platforms.
Can anyone tell me how can an JPEG image be divided in 8 x 8 blocks in C++.
Thanks.
Ah, the die-hard approach. My heart goes out to you. Expect to learn a lot, but be forewarned that you will lose time, blood and pain doing so.
The Compression FAQ has some details on how JPEG works. A good starting point is Part 2: Subject 75: Introduction to JPEG.
In a nutshell, for a typical JPEG file, you will have to reverse the encoding steps 6 to 4:
(6) extract the appropriate headers and image data from the JFIF container
(5) reverse the Huffman coding
(4) reverse the quantization
You should then be left with 8x8 blocks you could feed into an appropriate inverse DCT.
Wikipedia has some details on the JFIF format as well as Huffman tables and structure of the JPEG data within the JFIF.
I'm assuming you're looking to play with JPEG to learn about it? Because access to the raw encoded blocks is almost certainly not necessary if you have some practical application.
EDIT after seeing comments: If you just want to get a part of a very large JPEG without reading/decompressing the whole file, you could use ImageMagick's stream command. It allows you to get a subimage without reading the whole file. Use like e.g. stream -extract 8x8+16+16 large.jpeg block.rgb to get a 8x8 block starting at (16,16).
You have to decompress the image, use the turbojpg library (it's very fast), which will give you an array of unsigned char as RGB (or RGBA). Now you have an uncompressed image, which has a byte value for R G and B respectively.
You can from here, go and make a simple for loop that will go through 3*8 char blocks and copy them, using memcpy to some other memory location.
You have to keep in mind that the array returned from the turbojpg library is a one dimensional linear array of bytes. So the scanlines are stored one after the other. Take this into account when creating your blocks, cause depending on your needs, you'll have to traverse the array differently.
Does anyone know how to open an image, specifically a jpg, to a byte array in C or C++? Any form of help is appreciated.
Thanks!
The ImageMagick library can do this too, although often it provides enough image manipulation functions that you can do many things without needing to convert the image to a byte array and handle it yourself.
You could try the DevIL Image Library I've only used it in relation to OpenGL related things, but it also functions as just a plain image loading library.
Check out the source code for wxImage in the wxWidgets GUI Framework. You will most likely be interested in the *nix distribution.
Another alternative is the GNU Jpeg library.
Here is how I would do it using GDIPlus Bitmap.LockBits method defined in the header GdiPlusBitmap.h:
Gdiplus::BitmapData bitmapData;
Gdiplus::Rect rect(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
//get the bitmap data
if(Gdiplus::Ok == bitmap.LockBits(
&rect, //A rectangle structure that specifies the portion of the Bitmap to lock.
Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeWrite, //ImageLockMode values that specifies the access level (read/write) for the Bitmap.
bitmap.GetPixelFormat(),// PixelFormat values that specifies the data format of the Bitmap.
&bitmapData //BitmapData that will contain the information about the lock operation.
))
{
//get the lenght of the bitmap data in bytes
int len = bitmapData.Height * std::abs(bitmapData.Stride);
BYTE* buffer = new BYTE[len];
memcpy(bitmapData.Scan0, buffer, len);//copy it to an array of BYTEs
//...
//cleanup
pBitmapImageRot.UnlockBits(&bitmapData);
delete []buffer;
}
I have my students use netpbm to represent images because it comes with a handy C library, but you can also put images into text form, create them by hand, and so on. The nice thing here is that you can convert all sorts of images, not just JPEGs, into PBM format, using command-line tools the Unix way. The djpeg tool is available a number of places including the JPEG Club. Students with relatively little experience can write some fairly sophisticated programs using this format.
OpenCV can also do this.
http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/index.html
search for: "Accessing image elements"