Magickcore can't set/get a single pixel - c

I am using MagickCore in imagemagick Q8 and I can't set specific pixel, this is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <magick/MagickCore.h>
#include <string.h>
int main(int argc,char **argv)
{
Image *imagen;
ImageInfo *imagen_info;
ExceptionInfo *exception;
PixelPacket *q;
MagickCoreGenesis(*argv,MagickTrue);
exception=AcquireExceptionInfo();
imagen_info = AcquireImageInfo();
(void) CopyMagickString(imagen_info->filename,argv[1],MaxTextExtent);
ReadImage(imagen_info, exception);
q = GetAuthenticPixels(imagen,0,0,1,1,exception);
q->red = 255;
q->green = 123;
q->blue = 220;
SyncAuthenticPixels(imagen,exception);
/* Write the image then destroy it. */
WriteImage(imagen_info, imagen);
DestroyImage(imagen);
DestroyExceptionInfo(exception);
MagickCoreTerminus();
return 0;
}
I am trying to read an image from a file and then edit a pixel and then save image to disk.
What am I doing wrong?

From the example provided, your imagen variable remains in a NULL pointer. It should be assigned by the return value of ReadImage.
imagen = ReadImage(imagen_info, exception);
The only other issue I see would be the assignment of color values on the PixelPacket. Assuming your working with RGB, you would need to calculate the Quantum color value.
q->red = 255 * QuantumRange;
q->green = 123 * QuantumRange;
q->blue = 220 * QuantumRange;
Note: this will issue a compiler warning, see docs for working with colors

Related

erorr reading Rgb Images uisng imLIb2

I am trying to read a raw RGBA image using imLIb2 (https://docs.enlightenment.org/api/imlib2/html/ -> according to this page it seems like they accept RGBA data for images)
#include <Imlib2.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv)
{
/* an image handle */
Imlib_Image image;
/* load the image */
Imlib_Load_Error error;
image = imlib_load_image_with_error_return("rgba.raw", &error);
printf("load error:%d", error);
if (image)
{
imlib_context_set_image(image);
imlib_image_set_format("png");
/* save the image */
imlib_save_image("working.png");
}
else
{
printf("not loaded\n");
}
}
loading other images formats like png and Jpeg work properly but when trying to load an RGBA image I get the error "IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT". Could someone tell me if I am missing something or should add Some header to the RGBA image or should I call some more functions before opening an RGBA image?
If Imlib2 doesn't support reading RgbA images is there any alternative C-library that can read rgb image and do scaling like functions?
So this for if someone is facing the same issue
Thanks to #mark-setchell for contributing!!
magickcore Api is an alternative C-library that can be used to perform functions on raw RGB.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <magick/ImageMagick.h>
int main(int argc, char **argv)
{
ExceptionInfo
exception;
Image
*image,
*images,
*resize_image,
*thumbnails;
ImageInfo
*image_info;
/*
Initialize the image info structure and read an image.
*/
InitializeMagick(NULL);
GetExceptionInfo(&exception);
image_info = CloneImageInfo((ImageInfo *)NULL);
image_info->size = "1920x1080";
image_info->depth = 8;
(void)strcpy(image_info->filename, "image.rgba");
images = ReadImage(image_info, &exception);
if (images == (Image *)NULL)
exit(1);
resize_image = MinifyImage(images, &exception);
if (resize_image == (Image *)NULL)
printf("error \n");
DestroyImageInfo(image_info);
DestroyMagick();
return (0);
}
for reading raw images the depth and the WxH have to be specified for the image. the above is a very small example for reducing the size in half. (https://imagemagick.org/script/magick-core.php).

I keep getting an error when I try to define an element of a struct

I am teaching myself C. I followed a tutorial and got an image to move around on the screen. Now I am trying to do it on my own and understand how to modularize my code and know whats going on with it.
I built a struct to get player coordinates and called it into my game_loop.h file. but it don't let me set variables from the struct. I tried to include just the important bits to keep it concise. Let me know if I need to post the whole code.
What am I doing wrong.
//includes
#include "game_loop.h"
//main body
int main( int argc, char *argv[])
{
//TODO make game menu and link it here
//TODO make game loop and put it here
initSDL();
renderGame();
handleEvent();
//make game cleanup and put it her
destroySDL();
return 0;
}
int header file game_loop.h -->
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "player.h"
#define pSIZE 64
#define wWIDTH 1280
#define wHEIGHT 720
//variables for starting SDL
SDL_Event event;
SDL_Window *window = NULL;
SDL_Renderer *render = NULL;
SDL_Surface *bgSurface = NULL;
SDL_Texture *bgTexture = NULL;
SDL_Surface *pSurface = NULL;
SDL_Texture *pTexture = NULL;
int flags = 0; //window flags may need to change in the future
struct Player player;
player.x = 600;
player.y = 300;
void initSDL()
{
//initializing SDL
if(SDL_Init(SDL_INIT_VIDEO)!= 0)
{
printf("ERROR starting SDL: %s\n", SDL_GetError());
}else{printf("Starting SDL: Successful.\n");}
in a player.h file -->
struct Player{
int x;
int y;
};
You have lines of executable code outside of a function:
Player player;
player.x = 600;
player.y = 300;
The first line defines a variable. That is OK. The next two lines are not, as they are statements.
You need to initialize the struct at the time it is defined. You can do it as follows:
Player player = { 600, 300 };
Also, it's not a good idea to define variables in header files. If a header is used in multiple source files, you'll end up with errors due to multiple definitions.
In your header file, variables should be declared as extern without an initializer:
extern Player player;
Then you would put the definition with the initializer in exactly one source file.
Similarly for functions, put a declaration of the function in the header, and the definition of the function in one source file.

uEye Camera and OpenCV Memory Access

I am using a 35MM EO Megapixel Fixed FL Lens Edmund Optics camera, OpenCV 2.4.6, and Ubuntu 12.04 LTS as my development environment. I am also using C to develop, not C++. The camera has an API that I am following, and I believe I have set everything up correctly. I initialize the camera, set memory locations, and freeze the video. I then use OpenCV to get the image from memory, but my image is nothing like what it should be (may be seen below). Is my image data pulling data from a junk memory location? How can I access the image saved by "is_FreezeVideo" for image processing done by OpenCV? The image that is printed out can be seen here http://i.imgur.com/kW6aqB3.png
The code I am using is below.
#include "../Include/Camera.h"
#include <wchar.h>
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
//#include <opencv2/opencv.hpp>
#include <ueye.h>
// uEye variables
HIDS m_hCam; // handle to room
HWND m_hWndDisplay; // handle to diplay window
int m_Ret; // return value of uEye SDK functions
int m_nColorMode = 0; // Y8/RGB16/RGB24/REG32
int m_nBitsPerPixel=8; // number of bits needed store one pixel
int m_nSizeX = 1280; // width of video
int m_nSizeY = 1024; // height of video
int m_lMemoryId; // grabber memory - buffer ID
char* m_pcImageMemory; // grabber memory - pointer to buffer
int m_nRenderMode = IS_RENDER_FIT_TO_WINDOW; //render mode
void getAzimuth(){
}
void getElevation(){
}
void initializeCamera(){
if (m_hCam !=0 ) {
//free old image mem.
is_FreeImageMem (m_hCam, m_pcImageMemory, m_lMemoryId);
is_ExitCamera (m_hCam);
}
// init room
m_hCam = (HIDS) 0; // open next room
m_Ret = is_InitCamera (&m_hCam, NULL); // init room
if (m_Ret == IS_SUCCESS) {
// retrieve original image size
SENSORINFO sInfo;
is_GetSensorInfo (m_hCam, &sInfo);
m_nSizeX = sInfo.nMaxWidth;
m_nSizeY = sInfo.nMaxHeight;
printf("Width: %d Height: ", m_nSizeX, m_nSizeY);
// setup the color depth to the current windows setting
is_GetColorDepth (m_hCam, &m_nBitsPerPixel, &m_nColorMode);
is_SetColorMode (m_hCam, m_nColorMode);
//printf ("m_nBitsPerPixel=%i m_nColorMode=%i \n", m_nBitsPerPixel, IS_CM_BAYER_RG8);
// memory initialization
is_AllocImageMem (m_hCam, m_nSizeX, m_nSizeY, m_nBitsPerPixel, &m_pcImageMemory, &m_lMemoryId);
//set memory active
is_SetImageMem (m_hCam, m_pcImageMemory, m_lMemoryId);
// display initialization
is_SetImageSize (m_hCam, m_nSizeX, m_nSizeY);
is_SetImagePos(m_hCam, 0, 0);
is_SetDisplayMode (m_hCam, IS_SET_DM_DIB);
} else {
printf("No Camera Initialized! %c", 10);
}
if (m_hCam !=0) {
INT dummy;
char *pMem, *pLast;
double fps = 0.0;
if (is_FreezeVideo (m_hCam, IS_WAIT) == IS_SUCCESS) {
m_Ret = is_GetActiveImageMem(m_hCam, &pLast, &dummy);
m_Ret = is_GetImageMem(m_hCam, (void**)&pLast);
}
IplImage* tmpImg = cvCreateImageHeader (cvSize (m_nSizeX, m_nSizeY), IPL_DEPTH_8U, 1);
tmpImg->imageData = &m_pcImageMemory;
cvNamedWindow("src",1);
cvShowImage("src",tmpImg);
cvWaitKey(0);
}
}
Thanks
You need to use is_ImageFile function to save the image file to a filename.You can see the sample example from the is_ImageFile function.You can save it to the format(bmp,png,jpeg) you need.
regards,
Sreenivas
The problem was the camera properties. After setting brightness and other properties, we now get an actual image

Live graph for a C application

I have an application which logs periodically on to a host system it could be on a file or just a console. I would like to use this data to plot a statistical graph for me. I am not sure if I can use the live graph for my application.
If this tool is the right one, may I have an example on integrating the external application with the live graph?
this is livegraph link --> http://www.live-graph.org/download.html
I think this can be achieved easiest using Python plus matplotlib. To achieve this there are actually multiple ways: a) integrating the Python Interpreter directly in your C application, b) printing the data to stdout and piping this to a simple python script that does the actual plotting. In the following I will describe both approaches.
We have the following C application (e.g. plot.c). It uses the Python interpreter to interface with matplotlib's plotting functionality. The application is able to plot the data directly (when called like ./plot --plot-data) and to print the data to stdout (when called with any other argument set).
#include <Python.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
void initializePlotting() {
Py_Initialize();
// load matplotlib for plotting
PyRun_SimpleString(
"from matplotlib import pyplot as plt\n"
"plt.ion()\n"
"plt.show(block=False)\n"
);
}
void uninitializePlotting() {
PyRun_SimpleString("plt.ioff()\nplt.show()");
Py_Finalize();
}
void plotPoint2d(double x, double y) {
#define CMD_BUF_SIZE 256
static char command[CMD_BUF_SIZE];
snprintf(command, CMD_BUF_SIZE, "plt.plot([%f],[%f],'r.')", x, y);
PyRun_SimpleString(command);
PyRun_SimpleString("plt.gcf().canvas.flush_events()");
}
double myRandom() {
double sum = .0;
int count = 1e4;
int i;
for (i = 0; i < count; i++)
sum = sum + rand()/(double)RAND_MAX;
sum = sum/count;
return sum;
}
int main (int argc, const char** argv) {
bool plot = false;
if (argc == 2 && strcmp(argv[1], "--plot-data") == 0)
plot = true;
if (plot) initializePlotting();
// generate and plot the data
int i = 0;
for (i = 0; i < 100; i++) {
double x = myRandom(), y = myRandom();
if (plot) plotPoint2d(x,y);
else printf("%f %f\n", x, y);
}
if (plot) uninitializePlotting();
return 0;
}
You can build it like this:
$ gcc plot.c -I /usr/include/python2.7 -l python2.7 -o plot
And run it like:
$ ./plot --plot-data
Then it will run for some time plotting red dots onto an axis.
When you choose not to plot the data directly but to print it to the stdout you may do the plotting by an external program (e.g. a Python script named plot.py) that takes input from stdin, i.e. a pipe, and plots the data it gets.
To achieve this call the program like ./plot | python plot.py, with plot.py being similar to:
from matplotlib import pyplot as plt
plt.ion()
plt.show(block=False)
while True:
# read 2d data point from stdin
data = [float(x) for x in raw_input().split()]
assert len(data) == 2, "can only plot 2d data!"
x,y = data
# plot the data
plt.plot([x],[y],'r.')
plt.gcf().canvas.flush_events()
I have tested both approaches on my debian machine. It requires the packages python2.7 and python-matplotlib to be installed.
EDIT
I have just seen, that you wanted to plot a bar plot or such thing, this of course is also possible using matplotlib, e.g. a histogram:
from matplotlib import pyplot as plt
plt.ion()
plt.show(block=False)
values = list()
while True:
data = [float(x) for x in raw_input().split()]
values.append(data[0])
plt.clf()
plt.hist([values])
plt.gcf().canvas.flush_events()
Well, you only need to write your data in the given format of livegraph and set livegraph up to plot what you want. If wrote small C example which generates random numbers and dumps them together with the time every second. Next, you just attach the livegraph program to the file. That's it.
Playing around with LiveGraph I must say that its use is rather limited. I still would stick to a python script with matplotlib, since you have much more control over how and what is plotted.
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
int main(int argc, char** argv)
{
FILE *f;
gsl_rng *r = NULL;
const gsl_rng_type *T;
int seed = 31456;
double rndnum;
T = gsl_rng_ranlxs2;
r = gsl_rng_alloc(T);
gsl_rng_set(r, seed);
time_t t;
t = time(NULL);
f = fopen("test.lgdat", "a");
fprintf(f, "##;##\n");
fprintf(f,"#LiveGraph test file.\n");
fprintf(f,"Time;Dataset number\n");
for(;;){
rndnum = gsl_ran_gaussian(r, 1);
fprintf(f,"%f;%f\n", (double)t, rndnum);
sleep(1);
fflush(f);
t = time(NULL);
}
gsl_rng_free(r);
return 0;
}
compile with
gcc -Wall main.c `gsl-config --cflags --libs`

screenshot using openGL and/or X11

i am trying to get a screenshot of the screen or a window. I tried using functions from X11
and it works fine. The problem is that getting the pixels from XImage takes a lot of time.
Than i tried to look for some answers on how to do it using openGL. Here's what i've got:
#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
int main(int argc, char **argv)
{
int width=1200;
int height=800;
//_____________________________----
Display *dpy;
Window root;
GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
XVisualInfo *vi;
GLXContext glc;
dpy = XOpenDisplay(NULL);
if ( !dpy ) {
printf("\n\tcannot connect to X server\n\n");
exit(0);
}
root = DefaultRootWindow(dpy);
vi = glXChooseVisual(dpy, 0, att);
if (!vi) {
printf("\n\tno appropriate visual found\n\n");
exit(0);
}
glXMakeCurrent(dpy, root, glc);
glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
printf("vendor: %s\n", (const char*)glGetString(GL_VENDOR));
//____________________________________________
glXMakeCurrent(dpy, root, glc);
glEnable(GL_DEPTH_TEST);
GLubyte* pixelBuffer = new GLubyte[sizeof(GLubyte)*width*height*3*3];
glReadBuffer(GL_FRONT);
GLint ReadBuffer;
glGetIntegerv(GL_READ_BUFFER,&ReadBuffer);
glPixelStorei(GL_READ_BUFFER,GL_RGB);
GLint PackAlignment;
glGetIntegerv(GL_PACK_ALIGNMENT,&PackAlignment);
glPixelStorei(GL_PACK_ALIGNMENT,1);
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_INT, pixelBuffer);
int i;
for (i=0;i<100;i++) printf("%u\n",((unsigned int *)pixelBuffer)[i]);
return 0;
}
when i run the program it returns an error:
X Error of failed request: BadAccess (attempt to access private resource denied)
Major opcode of failed request: 199 ()
Minor opcode of failed request: 26
Serial number of failed request: 20
Current serial number in output stream: 20
if i comment the line with glXMakeCurrent(dpy, root, glc); before glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); it returns no erros, but all the pixels are 0.
How should i go about this problem? I am new to openGL and maybe i am missing something important here. Maybe also another way of getting pixels from the screen or specific window exists?
I don't think what you are trying to do is possible. You can't use OpenGL to read pixels from window you don't own and which probably don't even use OpenGL. You need to stick to X11.
If you have XImage you can get raw pixels from ximage->data. Just make sure you are reading it in correct format.
http://tronche.com/gui/x/xlib/graphics/images.html
You can use XShmGetImage, but you have to query the extensions of the X11 server first, to make sure MIT-SHM extension is available. You also need to know how to setup and use a shared memory segment for this.
Querying the Extension:
http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l224
Getting the image:
http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l537
The following runs once at 140 fps on my platform. xcb_image_get() (called with XCB_IMAGE_FORMAT_Z_PIXMAP) will store all pixels in ximg->data, pixel by pixel. On my platform, each pixel is 32 bits, each channel is 8 bits, and there's 3 channels (to 8 bits per pixel are unused).
/*
gcc ss.c -o ss -lxcb -lxcb-image && ./ss
*/
#include <stdio.h>
#include <xcb/xcb_image.h>
xcb_screen_t* xcb_get_screen(xcb_connection_t* connection){
const xcb_setup_t* setup = xcb_get_setup(connection); // I think we don't need to free/destroy this!
return xcb_setup_roots_iterator(setup).data;
}
void xcb_image_print(xcb_image_t* ximg){
printf("xcb_image_print() Printing a (%u,%u) `xcb_image_t` of %u bytes\n\n", ximg->height, ximg->width, ximg->size);
for(int i=0; i < ximg->size; i += 4){
printf(" ");
printf("%02x", ximg->data[i+3]);
printf("%02x", ximg->data[i+2]);
printf("%02x", ximg->data[i+1]);
printf("%02x", ximg->data[i+0]);
}
puts("\n");
}
int main(){
// Connect to the X server
xcb_connection_t* connection = xcb_connect(NULL, NULL);
xcb_screen_t* screen = xcb_get_screen(connection);
// Get pixels!
xcb_image_t* ximg = xcb_image_get(connection, screen->root, 0, 0, screen->width_in_pixels, screen->height_in_pixels, 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP);
// ... Now all pixels are in ximg->data!
xcb_image_print(ximg);
// Clean-up
xcb_image_destroy(ximg);
xcb_disconnect(connection);
}

Resources