How can I write in a buffer (unsigned char*) with MagickWand?
Currently I generate an image and save it to file, but I need it in memory:
MagickNewImage( wand, 640, 480, p_wand );
MagickWriteImage( wand, "test.jpg" );
According to the documentation there is a function MagickGetImageBlob that returns unsigned char * which is seemingly what you are looking for. Its exact documentation is
MagickGetImageBlob() implements direct to memory image formats. It returns the image as a blob (a formatted "file" in memory) and its length, starting from the current position in the image sequence. Use MagickSetImageFormat() to set the format to write to the blob (GIF, JPEG, PNG, etc.).
Note that this does require you to set the format using MagickSetImageFormat, but on the whole this seems to be the closest thing to what you are looking for.
Related
I have a file with a sequence of NxM unsigned integral values of fixed width - let's even assume they're single bytes - and I would like to "wrap" in some kind of common image file format. Preferably, something usable with popular image viewers; and otherwise with an image editor like GIMP.
What image format would require the minimum amount of conversion work, i.e. be as close as possible to just slapping some small header onto the raw data?
Notes:
This is a grayscale/intensity image - there are no color channels / interleaved values etc.
I don't care if the image format is row-major or column-major, i.e. if the image appears transposed relative to the order I wrote the data originally.
I've just noticed the Portable Pixmap Formats, which include the PGM format. The closest I've seen to a spec is on this page.
PGM files are supported by apps such as: Eye of Gnome (on Linux), IrfanView (on Windows), GIMP and others.
Create the image file programmatically
If I understand correctly, the following C function should convert the raw data OP has into a PGM file:
void write_pgm(FILE* file, size_t width, size_t height, uint8_t* data)
{
const char magic = "P5"; // for binary graymap
fprintf(file, "%2s %zu %zu 255\n", magic, width, height);
fwrite(data, 1, width * height, file);
}
This is a variation on a similar function for a PPM, here.
You can easily adapt this to whatever programming language you like.
Converting a file
So, suppose you've put your output in a file on disk. Apparently, there's a utility for making a PGM of it: rawtopgm. Here's a invocation for your case:
rawtopgm -bpp 1 -maxval 255 N M my_data_file > out.pgm
or, exploiting defaults:
rawtopgm N M my_data_file > out.pgm
pretty simple.
I just created a simple PDF Document containing a word "Test" in it and created a byte stream out of it in C# Console Application:
buff = File.ReadAllBytes(<Path of File>);
The size of the file is around 9,651 bytes. I also created a Win32 C dll that exports a function which takes the file byte array and the length of the byte array as an argument, declared in C# using this:
[DllImport("<path to dll>", CallingConvention = CallingConvention.Cdecl)]
public static extern int file_data(byte[] byteArray, int length);
The method in C dll is exported as below:
#define FILEDATA_API __declspec(dllexport)
FILEDATA_API int file_data(char *byteArray, int size);
I then invoked ret = file_data(buff, buff.length); and in the C code, wrote the character pointer received directly to a temp file character by character as below:
while (length> 0)
{
fprintf(outFile, "%c", *fileData); //fileData is the actual byte array received from C# Code
fileData++;
length--;
}
But the problem arises here, the C code that dumps out the byte array to a file character by character generates a file of size 9,755 bytes. Most of the content inside it seems to look correct, except some new lines that gets introduced(as far as i know and may be some additional data), which causes the PDF file to get corrupted and this dumped out version does not open in Adobe. Can someone please provide some pointers on where I might be going wrong? I cannot use %s in fprint since some combination of the byte array in the PDF results in null terminated string in C which then dumps out even lesser data than I expect.
Thanks.
UPDATE:
The desired behavior is that the file byte array as received from C#
and when written using C code to a file should make the file open
successfully in Adobe.
The code present in the problem should be
sufficient for someone to generate a win32 dll, that simply writes
out the char pointer to a file, but I have added few more details.
You're probably calling fopen without the b mode flag. Append b to your mode specifier:
FILE *outFile = fopen("file.txt", "wb")
From this site (emphasis mine):
Text files are files containing sequences of lines of text. Depending on the environment where the application runs, some special character conversion may occur in input/output operations in text mode to adapt them to a system-specific text file format. Although on some environments no conversions occur and both text files and binary files are treated the same way, using the appropriate mode improves portability.
In my experience, this "conversion" on Windows changes \n to \r\n at least.
In file text.txt I have this sentenc:
"Příliš žluťoučký kůň úpěl ďábelské ódy."
(I think Windows uses Windows-1250 code page to represent this text.)
In my program I save it to a buffer
char string[1000]
and render string with ttf to SDL_Surface *surface
surface = TTF_RenderText_Blended(font, string, color);
/*(font is true type and support this text)*/
But it gives me not correct result:
I need some reputation points to post images
so I can only describe that ř,í,š,ž,ť,ů,ň,ď are not displayed correctly.
Is it possible to use ttf for rendering this sentence correctly?
(I tried also TTF_RenderUTF8_Blended, TTF_RenderUNICODE_Solid... with worse result.)
The docs for TTF_RenderText_Blended say that it takes a Latin-1 string (Windows-1252) - this will be why it isn't working.
You'll need to convert your input text to UTF-8 and use RenderUTF8, or to UTF-16 and use RenderUNICODE to ensure it is interpreted correctly.
How you do this depends on what platform your app is targeted to - if it is Windows, then the easiest way would be to use the MultiByteToWideChar Win32 API to convert it to UTF-16 and then use the TTF_RenderUNICODE_Blended to draw it.
My solution will be this:
Three input files. In first file there will be a set of symbols from czech alphabet.
Second file will be sprite bitmap file where graphic symbols will be sorted in the
same order as in first file. In my program symbols from third input file will be compared with symbols from first file and right section of sprite will be copied on sreen one by one.
I will leave out sdl_ttf. It has some advantages and disadvantages but I think it will work for my purposes.
Thanks for all responses
Is there anyway in C to get an image, stream by stream and how can I understand how many stream there are in an Image?
the Image is in JPEEG type.
and for saving this stream in another file I'll have any problem?
You can have a look to the free OpenCV library : http://opencv.org/
Here there is a tutorial with some examples : http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/
It's largely used for this kind of treatments.
Without using any external library what you have as a jpeg image is simply a binary file. You may do whatever with it via fopen(), fscanf() or any other file functions.
for saving this stream in another file I'll have any problem?
No problem if you are just coping a jpeg image to another new file. But problem may be there if you change the image extension. Please have a look at here
i got a question for reading an bmp image. How can i get the pixel value(R, G, B values) in an bmp image?
Can anyone help me using the C programming language?
Note: you may need to grab an extra byte for the alpha values if your BMP has alpha channel. In that case image would be image[pixelcount][4], and you would add another getc(streamIn) line to hold that fourth index. My BMP turned out to not need that.
// super-simplified BMP read algorithm to pull out RGB data
// read image for coloring scheme
int image[1024][3]; // first number here is 1024 pixels in my image, 3 is for RGB values
FILE *streamIn;
streamIn = fopen("./mybitmap.bmp", "r");
if (streamIn == (FILE *)0){
printf("File opening error ocurred. Exiting program.\n");
exit(0);
}
int byte;
int count = 0;
for(i=0;i<54;i++) byte = getc(streamIn); // strip out BMP header
for(i=0;i<1024;i++){ // foreach pixel
image[i][2] = getc(streamIn); // use BMP 24bit with no alpha channel
image[i][1] = getc(streamIn); // BMP uses BGR but we want RGB, grab byte-by-byte
image[i][0] = getc(streamIn); // reverse-order array indexing fixes RGB issue...
printf("pixel %d : [%d,%d,%d]\n",i+1,image[i][0],image[i][1],image[i][2]);
}
fclose(streamIn);
~Locutus
The easy way would be to find a good image manipulation library for your chosen platform and use that.
Linux ImLib / GDK-Pixbuf (Gnome/GTK) / QT Image (KDE/Qt) should be able to do what you need.
Windows I'm not familiar with the appropriate system library, but an MSDN Search for "Bitmap" is probably a good place to start.
Mac OSX Cocoa has some image manipulation capabilities, see this article.
The hard way would be to open the file and actually interpret the binary data within. To do that you'll need the BMP File Specification. I'd recommend trying the easy way first.
You need to study the BMP file format. It is easier to read uncompressed 24-bit BMP files. They just contain a header at the beginning and RGB values of each pixel.
To start with this, check the example of 2x2 bitmap image at http://en.wikipedia.org/wiki/BMP_file_format. Follow the below steps.
Create the 2x2 BMP image shown on Wikipedia.
Open the file in binary mode using your C program.
Seek to byte position 54.
Read 3 bytes.
The bytes would be 0, 0 and 255 respectively. (Not sure whether the order is RGB. I had done this long back and I think the order is not RGB. Just verify this.)
As simple as that! Study the header of the BMP to understand more about the format.