Simple bitmap graphics in c++? - c++

I'm a Flash programmer and I'm currently exploring C++. In flash, you can create a bitmap and place it on the screen, and then use methods like getPixel(x, y), setPixel(x, y, c) ect. Press ctrl+enter and you can get started with what ever you want to do.
I use Visual C++ 2010. Since I've used Flash alot I'm used to simple and short commands. In C++ though, it's harder to figure out how to get a bitmap where you can manipulate pixels.
I don't know much about graphics enginges or 3D engines, it would be very useful information, but first I'd like to see what I can create with pixels, so do you know a simple way to create a manipulatable bitmap in C++? As optimized as possible, then I can write my own drawLine, drawCurve ect functions. :)

Because you mentioned Visual C++ 2010, I will assume that you are using Vista or higher and you want to first draw 2D graphics using the native Windows C++ approach. If this is the case, you want to use Direct2D. You may find old articles that use GDI, but this is the old way, so don't use it. Here is the link to MSDN introducing Direct2D.

If you really want to use C++ you should look at using GDI+ which is the standard windows/VS way of doing graphics. This is a slight highter level (friendlier) api than the older GDI api for doing graphics that dates back to (pre?) MFC days. You will need to get a basic grasp of device contexts etc... in order to understand how to load your bitmap from a file and get it on the screen.
CGI+ allows easy manipulation of a bitmap on a per pixel basis using the LockBits method. It can read most common image formats (bmp, jpg, png etc).
The example code below shows a typical load bitmap and read some pixels type code (it is taken verbatim from this msdn gdi+ article
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;
INT main() {
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Bitmap* bitmap = new Bitmap(L"LockBitsTest1.bmp");
BitmapData* bitmapData = new BitmapData;
Rect rect(20, 30, 5, 3);
// Lock a 5x3 rectangular portion of the bitmap for reading.
bitmap->LockBits(
&rect,
ImageLockModeRead,
PixelFormat32bppARGB,
bitmapData);
printf("The stride is %d.\n\n", bitmapData->Stride);
// Display the hexadecimal value of each pixel in the 5x3 rectangle.
UINT* pixels = (UINT*)bitmapData->Scan0;
for(UINT row = 0; row < 3; ++row) {
for(UINT col = 0; col < 5; ++col)
printf("%x\n", pixels[row * bitmapData->Stride / 4 + col]);
printf("- - - - - - - - - - \n");
}
bitmap->UnlockBits(bitmapData);
delete bitmapData;
delete bitmap;
GdiplusShutdown(gdiplusToken);
return 0;
}
As for draw line, draw curve etc routines - these are all found on the Graphics object in GDI+. Its the main object that sits between your code and the screen. A Graphics object would be used to render the above bitmap using Graphics.DrawImage.

Well the answer that is about to come is probably one you won't like, but I'll give it anyways :)
C++ has no notion of graphics output at all. Luckily, we have gotten a standardized way of printing text to the screen - but thats it. Really. No joking here.
However, most operating systems provide a means of graphics output (mostly via a C interface, as C is binary compatible to almost everything), and there are also C++ wrapper libraries that incorporate access to those. Dealing with OS issues is, however, a very different beast than C++ is (and thats kinda beast, I can tell ;).
Luckily, if you don't want to/have to understand the full story, I can recommend Qt (http://qt.nokia.com/products/) as a very decent library for GUI programming. And once you have a GUI window, you will also have the possibility to draw a bitmap into that GUI (I believe Qt has direct bitmap support and also the possibility to load images).
However, I will have to refer you to the tutorial docs of Qt, as even a simple introduction would go way over what would be a still understandable forum answer.
And this, I'm afraid, will be as easy as it can get drawing something onto the screen using C++. Nowhere near the simplicity of Flash for that purpose but in the end way more powerful.
Good luck.

You need external library to read images from file. Two libraries I like are SDL_image and stb_image. Both give you image in a format that lets you access and manipulate pixels.
Also to display the image you will need external library. SDL is popular and simple one.

Use PixelToaster if you just want easy access to a framebuffer.

Related

How to save a 1 bit per pixel png using stbi?

I struggled for a long time devising bitmap problems for students in C++ that were easy. The problem is the libraries which are not easy to use. stbi, an include-only library completely solved this problem and now students can easily load and save images, allowing me to focus on giving them problems in creating various images in a bitmap class, and then writing it out with a simple call.
https://github.com/nothings/stb
However, I want to do the same thing for a microprocessor class involving ARM assembler and i want a 1 bit per pixel bitmap, ideally a png. I cannot find an example writing out a png of this type. Does anyone know how to do it, preferably using stbi or simply and portably between windows, mac and linux using some other library?
The following would do it for a png with 4 bytes per pixel. I want 1 bit per pixel.
stbi_write_png("testpng_4.png", width, height, CHANNEL_NUM, pixels, width*CHANNEL_NUM);
Alternatively, I found that in libpng++ there is a cleaner API than libpng.
constexpr int W = 128, H = 128;
png::image< png::index_pixel > image(W,H);
png::palette pal(2);
pal[0] = png::color(0,0,0);
pal[1] = png::color(255,0,0);
image.set_palette(pal);
Can anyone tell me how to get the address of the image to work with the raw bits? The C++ API provides square brackets and I dug down a bit but can't find anything I can take an address of.

Is it possible to draw in another window (Using Opencv/ffmpeg

I realize this question might be closed with the "not enough research". However I did spent like 2 days googling for it and didn't find a conclusive answer.
Well I have an application that spawns a window, not written in c++. This application can have a c-interface with dlls. Now I wish to use the power of OpenCV, so I started on a dll to extend. Ss passing image data from/to the application is near impossible (only capable of passing c-strings & double values directly - using the hard drive for drawing is slowing down too much for real time image manipulation).
I am looking into letting opencv draw the image data directly - onto the window. I can gain the window handle easily, so would it then be possible to let openCV draw their data "over" the other window - or better into the other window?
Is this even possible with any library (FFMPEG, or something else)?
Yes, it's possible, but it's far from ideal. You can use GDI to draw on top of the other window (just convert IplImage to HBITMAP). Another technique is to do such drawing in a borderless layered window.
An easier approach is, since you own both applications, to write a function that passes an IplImage between them using standard C data types, after all, IplImage is nothing but a data type that is built from these standard types.
Here is how you will disassemble IplImage into 5 standard parameters:
The size (int, int) of the image (width/height);
The (int) bit depth of the image;
The number (int) of channels;
And the (unsigned char*) pixels of the image;
After receiving these parameters on the other side, you may wonder: how do I assemble a IplImage from scratch? Call cvCreateImageHeader() followed by cvSetData().

Manipulating a bitmap image in memory with linux

I've done a bit of research but haven't found anything useful so far.
In short I would like to be able to create a bitmap/canvas in memory and use an api which has functions for drawing primitive shapes and text on that bitmap and read the memory directly. This should be completely done in memory and not need a window system or something like Qt or GTK.
Why? I'm writing for the raspberry pi and am interfacing with a 256x64 4 bit greyscale OLED display over spi. This is all working fine so far. I've written a couple of functions for writing text etc, but am wondering if there is already a library I can use. I double buffer the display so I just need to manipulate the image in memory and then read the entire picture in one.
I can easily do this in windows but am not sure the best way to do this in linux
I've used Image Magick to do similar things. It supports Bitmap and SVG. http://www.imagemagick.org/script/index.php

Draw on DeviceContext from COLORREF[]

I have a pointer to a COLORREF buffer, something like: COLORREF* buf = new COLORREF[x*y];
A subroutine fills this buffer with color-information. Each COLORREF represents one pixel.
Now I want to draw this buffer to a device context. My current approach works, but is pretty slow (== ~200ms per drawing, depending on the size of the image):
for (size_t i = 0; i < pixelpos; ++i)
{
// Get X and Y coordinates from 1-dimensional buffer.
size_t y = i / wnd_size.cx;
size_t x = i % wnd_size.cx;
::SetPixelV(hDC, x, y, buf[i]);
}
Is there a way to do this faster; all at once, not one pixel after another?
I am not really familiar with the GDI. I heard about al lot of APIs like CreateDIBitmap(), BitBlt(), HBITMAP, CImage and all that stuff, but have no idea how to apply it. It seems all pretty complicated...
MFC is also welcome.
Any ideas?
Thanks in advance.
(Background: the subroutine I mentioned above is an OpenCL kernel - the GPU calculates an Mandelbrot image and safes it in the COLORREF buffer.)
EDIT:
Thank you all for your suggestions. The answers (and links) gave me some insight into Windows graphics programming. The performance is now acceptable (semi-realtime-scrolling into the Mandelbrot works :)
I ended up with the following solution (MFC):
...
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);
CBitmap mandelbrotBmp;
mandelbrotBmp.CreateBitmap(clientRect.Width(), clientRect.Height(), 1, 32, buf);
CBitmap* oldBmp = dcMemory.SelectObject(&mandelbrotBmp);
pDC->BitBlt(0, 0, clientRect.Width(), clientRect.Height(), &dcMemory, 0, 0, SRCCOPY);
dcMemory.SelectObject(oldBmp);
mandelbrotBmp.DeleteObject();
So basically CBitmap::CreateBitmap() saved me from using the raw API (which I still do not fully understand). The example in the documentation of CDC::CreateCompatibleDC was also helpful.
My Mandelbrot is now blue - using SetPixelV() it was red. But I guess that has something to do with CBitmap::CreateBitmap() interpreting my buffer, not really important.
I might try the OpenGL suggestion because it would have been the much more logical choice and I wanted to try OpenCL under Linux anyway.
Under the circumstances, I'd probably use a DIB section (which you create with CreateDIBSection). A DIB section is a bitmap that allows you to access the contents directly as an array, but still use it with all the usual GDI functions.
I think that'll give you the best performance of anything based on GDI. If you need better, then #Kornel is basically correct -- you'll need to switch to something that has more direct support for hardware acceleration (DirectX or OpenGL -- though IMO, OpenGL is a much better choice for the job than DirectX).
Given that you're currently doing the calculation in OpenCL and depositing the output in a color buffer, OpenGL would be the really obvious choice. In particular, you can have OpenCL deposit the output in an OpenGL texture, then you have OpenGL draw a quad using that texture. Alternatively, since you're just putting the output on screen anyway, you could just do the calculation in an OpenGL fragment shader (or, of course, a DirectX pixel shader), so you wouldn't put the output into memory off-screen just so you can copy the result onto the screen. If memory serves, the Orange book has a Mandelbrot shader as one of its examples.
Yes, sure, that's slow. You are making a round-trip through the kernel and video device driver for each individual pixel. You make it fast by drawing to memory first, then update the screen in one fell swoop. That takes, say, CreateDIBitmap, CreateCompatibleDc() and BitBlt().
This isn't a good time and place for an extensive tutorial on graphics programming. It is well covered by any introductory text on GDI and/or Windows API programming. Everything you'll need to know you can find in Petzold's seminal Programming Windows.
Since you already have an array of pixels, you can directly use BitBlt to transfer it to the window's DC. See this link for a partial example:
http://msdn.microsoft.com/en-us/library/aa928058.aspx

Convert image into useable byte array in C?

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"