I am trying to set a background image for one of my windows created with Xlib.
I would like the image to be a JPEG or PNG. I downloaded DevIL (which I prefer to use because it supports a lot of formats).
So, my questions, is, how do I do it? I can't find any specific tutorial or help.
I understand how I can use DevIL to load an image into a stream, but how do I put that on the window? I found an answer here: Load image onto a window using xlib but I don't know how and which function should receive the image bytes.
As I also understand, I should have a XImage that would hold all the image, and which I would use with XPutImage. What I don't understand is how do I send the image's bytes from DevIL to XImage.
Does somebody know any helpful page or maybe some clues about how I should do it?
Thanks!
The Xlib function used to create an XImage is XCreateImage, and its usage looks like this (you can read a full description in the link):
XImage *XCreateImage(display, visual, depth, format, offset, data,
width, height, bitmap_pad, bytes_per_line)
where the relevant argument for your specific question would be data, a char* that points to where you keep the image data loaded in with DevIL. With this, you should then be able to follow the steps in the other answer you already found.
Edited to add:
You still have to tell DevIL how to format your image data so that XCreateImage can understand it. For example the following pair of function calls will create an XImage that appears correctly:
ilCopyPixels(
0, 0, 0,
image_width, image_height, 1,
IL_BGRA, IL_UNSIGNED_BYTE,
image_data
);
// ...
XImage* background = XCreateImage(
display,
XDefaultVisual(display, XDefaultScreen(display)),
XDefaultDepth(display, XDefaultScreen(display)),
ZPixmap,
0,
image_data,
image_width,
image_height,
32,
0
);
, if you instead chose IL_RGBA, the colors will be off!
Related
I've gotten an XImage object from XGetImage() from a screenshot, but now I don't know what to do with it. I'm using C++. Thanks.
The next best thing you could do, would be to use XPutImage() or use some other X11 image manipulation function.
Here you can find some examples, reading/changing some pixels, as well as a little more about the XImage data structure.
I'm working in a project where Cairo was chosen as the graphics library (running on Xlib) in an OpenSUSE Linux environment. I have very little experience working with graphics libraries or graphic file formats, and I was wondering if it is possible to draw a Windows bitmap image to a Cairo surface? It appears to be relatively straightforward to draw a png in Cairo, but I've been looking around everywhere for information on drawing bitmaps and couldn't really find anything. I pieced together the following code:
int height = 256;
int width = 256;
cairo_format_t format = CAIRO_FORMAT_RGB24;
int stride = cairo_format_stride_for_width (format, width);
unsigned char *bitmapData;
bitmapData = (unsigned char *)(malloc (stride * height));
std::ifstream myFile ("exampleBitmapImage.bmp", std::ios::in | std::ios::binary);
myFile.read ((char *)bitmapData, stride * height);
cairo_surface_t *imageSurface = cairo_image_surface_create_for_data (bitmapData, format, width, height, stride);
cairo_set_source_surface (cs, imageSurface, 0, 0);
cairo_paint (cs);
cairo_show_page (cs);
cairo_surface_destroy (imageSurface);
myFile.close();
Strangely, when I run this it displays the image upside-down and backwards at 1/64 of its size 8 times in a row, and then fills out what would be the remainder of the image size (the remaining 7/8 of the image) with black. I suspect it has something to do with the file format, and that I'm parsing and feeding the binary data incorrectly and with improper settings to Cairo. Can anyone give guidance on how to get this working properly? I apologize for my lack of knowledge and wish to understand this problem better, and any help is greatly appreciated, thanks! :)
Multiply the stride with -1 that should flip your bitmap.
Look up the BMP file format http://en.wikipedia.org/wiki/BMP_file_format and
implement bitmap header parser and set the encoding correctly.
Right now are guessing the encoding as RGB24 and you have Cairo interpretting the bitmap header as image data.
I'm trying to use pictureBox->Image (Windows Forms) to display a cv::Mat image (openCV). I want to do that without saving the Image as a file ('cause i want to reset the image every 100ms).
I just found that topic here: How to display a cv::Mat in a Windows Form application?
When i use this solution the image appears to be white only. I guess i took the wrong PixelFormat.
So how do figure out the PixelFormat i need? Haven't seen any Method in cv::Mat to get info about that. Or does this depend on the image Source i use to create this cv::Mat?
Thanks so far :)
Here i took a screen. Its not completely white. So i guess there is some color info. But maybe i'm wrong.
Screen
cv::Mat.depth() returns the pixel type, eg. CV_8U for 8bit unsigned etc.
and cv::Mat.channels() returns the number of channels, typically 3 for a colour image
For 'regular images' opencv generally uses 8bit BGR colour order which should map directly onto a Windows bitmap or most Windows libs.
SO you probably want system.drawing.imaging.pixelformat.Format24bppRgb, I don't know what order ( RGB or BGR) it uses but you can use the opencv cv::cvtColor() with CV_BGR2RGB to convert to RGB
Thanks for the help! The problem was something else.
I just did not allocate memory for the Image Object. So there was nothing to really display.
Using cv::Mat img; in the headerFile and img = new cv::Mat(120,160,0); in Constructor (ocvcamimg Class) got it to work. (ocvcamimg->captureCamMatImg() returns img).
I have an OpenGL game, and I want to save what's shown on the screen to a video.
How can I do that? Is there any library or how-to-do-it?
I don't care about compression, I need the most efficient way so hopefully the FPS won't drop.
EDIT:
It's OpenGL 1.1 and it's working on Mac OSX though I need it to be portable.
There most certainly are great video capture software out there you could use to capture your screen, even when running a full screen OpenGL game.
If you are using new versions of OpenGL, as genpfault has mentioned you can use PBOs. If you are using legacy OpenGL (version 1.x), here's how you can capture the screen:
glFinish(); // Make sure everything is drawn
glReadBuffer(GL_FRONT);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glReadPixels(blx, bly, w, h, mode, GL_UNSIGNED_BYTE, GL_BGRA);
where blx and bly are the bottom left coordinates of the part of the screen you want to capture (in your case (0, 0)) and w and h are the width and height of the box to be captured. See the reference for glReadPixels for more info, such as the last parameter.
Writing captured screen (at your desired rate, for example 24 fps) to a video file is a simple matter of choosing the file format you want (for example raw video), write the header of the video and write the images (image by image if raw, or image differences in some other format etc)
Use Pixel Buffer Objects (PBOs).
I have some code that looks like this:
cairo_surface_t * surface = cairo_svg_surface_create("0.svg", 512, 512);
cairo_t * context = cairo_create(surface);
int * data = new int[512*512];
// fill the data...
cairo_surface_t * image_surface =
cairo_image_surface_for_data(data, 512, 512, 512*4);
cairo_set_source_surface(context, image_surface, 0, 0);
cairo_paint(context);
// do some other drawing ...
cairo_surface_flush(surface);
cairo_surface_finish(surface);
cairo_surface_destroy(surface);
cairo_destroy(context);
However, the svg always appears corrupted. The image is not properly written, and all drawing commands following do not work. Changing the surface type to PS, ie:
cairo_surface_t * surface = cairo_ps_surface_create("0.ps", 512, 512);
produces a perfectly correct PS document.
Any help fixing the SVG would be appreciated.
EDIT: Forgot to provide version info.
Cairo 1.10.2 as given by cairo_version_string().
g++ 4.52
Running on Ubuntu 11.04
EDIT(2): Ok, I have traced this down to PNG problems with cairo and discovered that cairo_surface_write_to_png does not behave as expected either. Both this function and attempting to embed an image in an SVG cause "out of memory errors", and I still don't know
why.
Looks like you may have forgotten to specify the SVG version as:
cairo_svg_surface_restrict_to_version (surface, CAIRO_SVG_VERSION_1_2);
You can do this immediately after creating the surface.
Perhaps publishing the resulting plain SVG can help.
I cannot find cairo_image_surface_for_data in the Cairo documentation. Did you mean cairo_image_surface_create_for_data? If so, you need to use cairo_format_stride_for_width to calculate the array size, and the bitmap data needs to be in the format Cairo expects. Since both of your outputs are corrupted, this strongly suggests that the problem is with the input.