Greetings
I am trying to create a new image following the example(s) on the web page documentation:
char* data;
size_t data = columns*rows;
data = (char*) new char[data_size];
Magick::Image image(columns, rows, "RGB", (MagickCore::StorageType)0, data);
I get the error: ImageMagick: unrecognized pixel map 'RGB'
This seems like it should at least create the object. The pixel buffer may not be correct.
Is there a better way to create new images? I want to create some synthetic images to test a signal processing algorithm.
Cheers
Mike
Image constructor throws exception
Re: Image constructor throws exception
Here is an example program that converts CMYK image data instead of RGB but it does prove the constructor works properly. We're using ImageMagick 6.5.7-4:
Code: Select all
#include <iostream>
#include <Magick++.h>
unsigned char imageData[] = {
0xff, 0xff, 0xff, 0xff, // super black
0x00, 0x00, 0x00, 0x00, // white
0xff, 0x00, 0x00, 0x00, // cyan
0x00, 0xff, 0x00, 0x00, // magenta
0x00, 0x00, 0xff, 0x00, // yellow
0x00, 0x00, 0x00, 0xff, // black
0x00, 0xff, 0xff, 0x00, // red
0xff, 0x00, 0xff, 0x00, // green
0xff, 0xff, 0x00, 0x00, // blue
0x00, 0x00, 0x00, 0x00, // white
0xff, 0xff, 0xff, 0xff // super black
};
#define IMAGE_WIDTH 11
#define IMAGE_HEIGHT 1
unsigned char outputImage[IMAGE_WIDTH * IMAGE_HEIGHT * 4];
int main (int argc, char * const argv[]) {
std::cout << "Hello, World!\n";
Magick::Image image( IMAGE_WIDTH, IMAGE_HEIGHT, "CMYK", Magick::CharPixel, imageData );
//image.type(Magick::TrueColorType);
image.write("/tmp/test.tif");
image.modifyImage();
//image.blur(30, 10);
image.syncPixels();
Magick::Pixels view(image);
FILE *f = fopen("/tmp/test.txt", "w");
for ( int row = 0; row < IMAGE_HEIGHT ; ++row )
{
Magick::PixelPacket *pixels = view.get(0,row,IMAGE_WIDTH,1);
Magick::IndexPacket *indexes = view.indexes();
for ( int column = 0; column < IMAGE_WIDTH ; ++column ) {
fprintf(f, "%8d\t%8d\t%8d\t%8d\n",
pixels->red, pixels->green, pixels->blue, *indexes);
pixels++;
indexes++;
}
}
fprintf(f, "\n");
fclose(f);
return 0;
}
Re: Image constructor throws exception
Thanks. I tried it and it works.
let me ask another question along the same line, although it may be some key fact I've forgotten about c++.
I'd like big images, about 2000x2000 or so. I substituted unsigned char *imageData = new unsigned char[N]; for the data statement in the code just to see if it will run. When N gets bigger than 40000 and the image is bigger than 200x200, I start getting seg faults. Is there some limit somewhere I've ignored? It seems like I should be able to create images of more or less arbitrary size.
Thanks
Mike
let me ask another question along the same line, although it may be some key fact I've forgotten about c++.
I'd like big images, about 2000x2000 or so. I substituted unsigned char *imageData = new unsigned char[N]; for the data statement in the code just to see if it will run. When N gets bigger than 40000 and the image is bigger than 200x200, I start getting seg faults. Is there some limit somewhere I've ignored? It seems like I should be able to create images of more or less arbitrary size.
Thanks
Mike
Re: Image constructor throws exception
There is no limit on image size other than if your system runs out of temporary space on disk to store the intermediate pixel data. Post a complete smallish program that illustrates the problem. Hopefully it will fail for us and we'll produce a stack trace to identify where the fault lies.
Re: Image constructor throws exception
Here's a small method that will seg fault:
I checked my /tmp space and realized it was mounted as tmpfs, i.e., in memory. I set the size to 4G and remounted it but get the same error.
Thanks for the help
Mike
Code: Select all
#include <iostream>
#include <Magick++.h>
unsigned char *imageData = new unsigned char[1000000];
#define IMAGE_WIDTH 1000
#define IMAGE_HEIGHT 1000
unsigned char outputImage[IMAGE_WIDTH * IMAGE_HEIGHT * 4];
int main (int argc, char * const argv[])
{
std::cout << "Hello, World!\n";
Magick::Image image( IMAGE_WIDTH, IMAGE_HEIGHT, "CMYK", Magick::CharPixel, imageData );
return 0;
}
Thanks for the help
Mike
Re: Image constructor throws exception
The default ImageMagick distribution is Q16, 16-bits per pixel component. You may need a constructor that specifies a depth of 8 otherwise its looking for 2 bytes per pixel instead of 1. Another option is to use the Q8 version of ImageMagick at 8-bits per pixel component.
Re: Image constructor throws exception
Hello again
A short test code:
I've been running this the debugger trying to sort the problem out. Note that I changed the data type to short. In the debugger I see:
Program received signal SIGSEGV, Segmentation fault.
ImportImagePixels (image=0xbd45770, x_offset=0, y_offset=0, columns=1000, rows=1000, map=<value optimized out>,
type=ShortPixel, pixels=0x2b409dfe8000) at magick/pixel.c:3315
3315 q->red=ScaleShortToQuantum(*p);
Current language: auto; currently c
(gdb) where
#0 ImportImagePixels (image=0xbd45770, x_offset=0, y_offset=0, columns=1000, rows=1000,
map=<value optimized out>, type=ShortPixel, pixels=0x2b409dfe8000) at magick/pixel.c:3315
#1 0x00002b409d279c3c in ConstituteImage (columns=1000, rows=1000, map=0xbd451e8 "CMYK", storage=ShortPixel,
pixels=0x2b409ddfe010, exception=0x7fff0d8bdf80) at magick/constitute.c:152
#2 0x00002b409d69bd5b in Magick::Image::read (this=0x7fff0d8be090, width_=1000, height_=1000,
map_=@0x7fff0d8be010, type_=MagickCore::ShortPixel, pixels_=0x2b409ddfe010) at Magick++/lib/Image.cpp:1619
#3 0x00002b409d69e47a in Image (this=0x7fff0d8be090, width_=1000, height_=1000, map_=@0x7fff0d8be0a0,
type_=MagickCore::ShortPixel, pixels_=0x2b409ddfe010) at Magick++/lib/Image.cpp:263
#4 0x0000000000400c5a in main (argc=1, argv=0x7fff0d8be1a8) at small_test_image.cpp:14
(gdb) print p
$1 = (const short unsigned int *) 0x2b409dfe8000
I note that the value of the pointer pixels is changed in the ImportImagePixels method while it is unchanged up to that call. If I decrease the size of the buffer from 1000000 to 10000 (i.e., 100x100 pixels of short) then the address _does_not_ change and the method runs to completion. This behavior baffles me. In my naivete I might believe that somehow a copy constructor got fouled up. Pass-by-reference is the norm for c++, isn't it? Can anybody suggest what might be going on here?
thanks
Mike
A short test code:
Code: Select all
#include <iostream>
#include <Magick++.h>
unsigned short *imageData = new unsigned short[1000000];
#define IMAGE_WIDTH 1000
#define IMAGE_HEIGHT 1000
unsigned char outputImage[IMAGE_WIDTH * IMAGE_HEIGHT * 4];
int main (int argc, char * const argv[])
{
std::cout << "Hello, World!\n";
Magick::Image image( IMAGE_WIDTH, IMAGE_HEIGHT, "CMYK", Magick::ShortPixel, imageData );
return 0;
}
Program received signal SIGSEGV, Segmentation fault.
ImportImagePixels (image=0xbd45770, x_offset=0, y_offset=0, columns=1000, rows=1000, map=<value optimized out>,
type=ShortPixel, pixels=0x2b409dfe8000) at magick/pixel.c:3315
3315 q->red=ScaleShortToQuantum(*p);
Current language: auto; currently c
(gdb) where
#0 ImportImagePixels (image=0xbd45770, x_offset=0, y_offset=0, columns=1000, rows=1000,
map=<value optimized out>, type=ShortPixel, pixels=0x2b409dfe8000) at magick/pixel.c:3315
#1 0x00002b409d279c3c in ConstituteImage (columns=1000, rows=1000, map=0xbd451e8 "CMYK", storage=ShortPixel,
pixels=0x2b409ddfe010, exception=0x7fff0d8bdf80) at magick/constitute.c:152
#2 0x00002b409d69bd5b in Magick::Image::read (this=0x7fff0d8be090, width_=1000, height_=1000,
map_=@0x7fff0d8be010, type_=MagickCore::ShortPixel, pixels_=0x2b409ddfe010) at Magick++/lib/Image.cpp:1619
#3 0x00002b409d69e47a in Image (this=0x7fff0d8be090, width_=1000, height_=1000, map_=@0x7fff0d8be0a0,
type_=MagickCore::ShortPixel, pixels_=0x2b409ddfe010) at Magick++/lib/Image.cpp:263
#4 0x0000000000400c5a in main (argc=1, argv=0x7fff0d8be1a8) at small_test_image.cpp:14
(gdb) print p
$1 = (const short unsigned int *) 0x2b409dfe8000
I note that the value of the pointer pixels is changed in the ImportImagePixels method while it is unchanged up to that call. If I decrease the size of the buffer from 1000000 to 10000 (i.e., 100x100 pixels of short) then the address _does_not_ change and the method runs to completion. This behavior baffles me. In my naivete I might believe that somehow a copy constructor got fouled up. Pass-by-reference is the norm for c++, isn't it? Can anybody suggest what might be going on here?
thanks
Mike
Re: Image constructor throws exception
CMYK is 4 pixel components, whereas your imageData array only provides for 1 pixel component. Try this instead:
- unsigned short *imageData = new unsigned short[4*1000000];
Re: Image constructor throws exception
Thanks. That was the problem.
I owe you a beer.
Mike
I owe you a beer.
Mike