How to combine images using MagickWand C API? - c

I have a two images And I want to combine them together, similar command for this is convert one.png two.png +clone -combine displaceMask.png.
Below is my C Code. I'm not getting the perfect result using C.
#include <stdio.h>
#include "MagickWand/MagickWand.h"
int main(int argc, const char * argv[]) {
MagickWand *wand1, *wand2, *wand3;
wand1 = NewMagickWand();
wand2 = NewMagickWand();
wand3 = NewMagickWand();
MagickReadImage(wand1, "one.png");
MagickReadImage(wand2, "two.png");
// convert one.png two.png +clone -combine displaceMask.png
wand3 = CloneMagickWand(wand2);
MagickAddImage(wand1, wand2);
MagickAddImage(wand1, wand3);
MagickCombineImages(wand1,RGBColorspace);
MagickWriteImage(wand1,"merge.png");
if(wand1)wand1 = DestroyMagickWand(wand1);
if(wand2)wand2 = DestroyMagickWand(wand2);
if(wand3)wand3 = DestroyMagickWand(wand3);
MagickWandTerminus();
return 0;
}
These are the images.
one.png
two.png
finalResultUsingCMd.png
merge.png (This image I'm getting using C code. But I want a above image.)

Updated Answer
In addition to capturing combine results, you'll need to reset the wand iterator before applying the MagickCombineImages. This is because each time you invoke MagickAddImage the internal linked list is pointing to the newly added node. (Hope I explained that clearly.)
Quoting some documents...
After using any images added to the wand using MagickAddImage() or MagickReadImage() will be prepended before any image in the wand.
Also the current image has been set to the first image (if any) in the Magick Wand. Using MagickNextImage() will then set teh current image to the second image in the list (if present).
This operation is similar to MagickResetIterator() but differs in how MagickAddImage(), MagickReadImage(), and MagickNextImage() behaves afterward.
So your example code should look like ...
#include "MagickWand/MagickWand.h"
int main(int argc, const char * argv[]) {
MagickWand
*wand1,
*wand2,
*wand3,
*result;
wand1 = NewMagickWand();
wand2 = NewMagickWand();
MagickReadImage(wand1, "one.png");
MagickReadImage(wand2, "two.png");
// convert one.png two.png +clone -combine displaceMask.png
wand3 = CloneMagickWand(wand2);
MagickAddImage(wand1, wand2);
MagickAddImage(wand1, wand3);
MagickSetFirstIterator(wand1);
result = MagickCombineImages(wand1, MagickGetImageColorspace(wand1));
MagickWriteImage(result,"merge.png");
wand1 = DestroyMagickWand(wand1);
wand2 = DestroyMagickWand(wand2);
wand3 = DestroyMagickWand(wand3);
result = DestroyMagickWand(result);
MagickWandTerminus();
return 0;
}
Original Answer
The MagickCombineImages method should return a pointer MagickWand * containing the result of the combine action. The behavior of this method has changed between version of IM 6 & IM 7, so it's more than possible that a bug exists, or implementation has adjusted. I'm not around IM 7 to verify at the moment, but here's a work around.
// convert one.png two.png +clone -combine displaceMask.png
wand3 = CloneMagickWand(wand2);
MagickCompositeImage(wand1, wand2, CopyGreenCompositeOp, MagickTrue, 0, 0);
MagickCompositeImage(wand1, wand3, CopyBlueCompositeOp, MagickTrue, 0, 0);
MagickWriteImage(wand1, "merge.png");

Related

Which lines are necessary to use espeak in our C/C++ program?

I found this code on the internet:
#include <string.h>
#include <malloc.h>
#include <espeak/speak_lib.h>
espeak_POSITION_TYPE position_type;
espeak_AUDIO_OUTPUT output;
char *path=NULL;
int Buflength = 1000, Options=0;
void* user_data;
t_espeak_callback *SynthCallback;
espeak_PARAMETER Parm;
char Voice[] = {"English"};
char text[30] = {"this is a english test"};
unsigned int Size,position=0, end_position=0, flags=espeakCHARS_AUTO, *unique_identifier;
int main(int argc, char* argv[] )
{
output = AUDIO_OUTPUT_PLAYBACK;
int I, Run = 1, L;
espeak_Initialize(output, Buflength, path, Options );
espeak_SetVoiceByName(Voice);
const char *langNativeString = "en"; //Default to US English
espeak_VOICE voice;
memset(&voice, 0, sizeof(espeak_VOICE)); // Zero out the voice first
voice.languages = langNativeString;
voice.name = "US";
voice.variant = 2;
voice.gender = 1;
espeak_SetVoiceByProperties(&voice);
Size = strlen(text)+1;
espeak_Synth( text, Size, position, position_type, end_position, flags,
unique_identifier, user_data );
espeak_Synchronize( );
return 0;
}
I only want the espeak reads my strings in my program, and the above code can do it, but I want to know, are all of this code necessary for that purpose? (I mean is it possible to simplifying it?)
***Also I like to know are there a way to using espeak as a system function? I mean system("espeak "something" "); ?
The usage of eSpeak itself seems pretty minimal - you need to read the documentation for that. There are some minor C coding simplifications possible, but perhaps hardly worth the effort:
The memset() is unnecessary. The structure can be initialised to zero thus:
espeak_VOICE voice = {0} ;
If you declare text thus:
char text[] = "this is a English test";
Then you can avoid using strlen() and replace Size with sizeof(text).
The variables I, Run and L are unused and can be removed.
To be able to pass the text as a string on the command line, and thus be able to issue system( "espeak \"Say Something\"") ; for example, you simply need to pass argv[1] to espeak_Synth() instead of text (but you will need to reinstate the strlen() call to get the size.

How to use MagickGetImageHistogram of ImageMagick C API

I have been using ImageMagick's C API using LuaJIT and FFI library and magick lua module for this. Now I want to use MagickGetImageHistogram method. So when it comes to pass an argument check my below code.
***image.lua***
local len = ffi.new("size_t[?]", 5)
local t = handle_result(self, lib.MagickGetImageHistogram(self.wand, len))
***lib.lua***
local ffi = require("ffi")
local lib
ffi.cdef([[ typedef void MagickWand;
typedef void PixelWand;
typedef int MagickBooleanType;
typedef int ExceptionType;
typedef int ssize_t;
typedef int CompositeOperator;
typedef int GravityType;
typedef int OrientationType;
typedef int InterlaceType;
typedef char DistortMethod[];
void MagickWandGenesis();
MagickWand* NewMagickWand();
PixelWand **MagickGetImageHistogram(MagickWand *wand, size_t *number_colors);
So I'm sure that my first argument is correct but not sure about second one.
And it returns the image histogram as an array of PixelWand wands. So how do I convert it to LuaJIT structure?
I'm not sure about the lua parts of the question, but the expected behavior MagickGetImageHistogram is as follows.
Method will return an array of pixel pointers.
Argument size_t *number_colors will be updated with the count of pixels in array.
Each pixel in array will need to invoke method PixelGetColorCount to retrieve the sum of pixels used by image.
Here's a quick example in C.
#include <stdio.h>
#include <wand/MagickWand.h>
int main(int argc, const char * argv[]) {
// Prototype vars
MagickWand * wand;
PixelWand ** histogram;
size_t histogram_count = 0;
// Boot environment.
MagickWandGenesis();
// Allocate & read image
wand = NewMagickWand();
MagickReadImage(wand, "rose:");
// Get Histogram as array of pixels
histogram = MagickGetImageHistogram(wand, &histogram_count);
// Iterate over each pixel & dump info.
for (int i = 0; i < histogram_count; ++i)
{
printf("%s => %zu\n",
PixelGetColorAsString(histogram[i]),
PixelGetColorCount(histogram[i]));
}
// Clean-up
histogram = DestroyPixelWands(histogram, histogram_count);
wand = DestroyMagickWand(wand);
MagickWandTerminus();
return 0;
}
This example will output the expected text...
// ...
srgb(48,45,43) => 1
srgb(50,45,42) => 2
srgb(50,44,43) => 5
srgb(51,45,43) => 1
// ...
So I would guess your lua script would look something like..
***image.lua***
local tlen = ffi.new("size_t[1]")
local t = lib.MagickGetImageHistogram(self.wand, tlen)
for i=0,tlen[0] do
handle_new_pixel(self, t[i], lib.PixelGetColorCount(t[i]))
end

Taking a screenshot using imagemagick API

I'm using GCC 4.7.2, C89, and ImageMagick-6.8.0-4.
I am trying to take a screen shot using the ImageMagick API. I have downloaded, compiled, and installed the headers and libraries.
However, I can't see in the documentation the API calls to do the screen shot. I will be linking and including the headers so that I can call the API from my C program. I just want the name of the function I will have to use to do this.
Can anyone point me in the right direction? Can ImageMagick take screenshots?
Using 'x:' Special File Format
If you want a no-thrill screen grab; you can invoke ImageMagick's import command by passing "x:root" as the source argument in MagickReadImage. The x: format allows for a full screenshot or a single window by passing a pid or window label. Additional modifiers can capture regions & paging.
#include <wand/MagickWand.h>
int main(int argc, char **argv)
{
MagickWandGenesis();
MagickWand *wand = NULL;
wand = NewMagickWand();
MagickReadImage(wand,"x:root"); // <-- Invoke ImportImageCommand
MagickWriteImage(wand,"screen_shot.png");
if(wand)wand = DestroyMagickWand(wand);
MagickWandTerminus();
return 0;
}
Use Additional 'magick' Libraries
Outside of wand libraries, magick/xwindow.h allows you to import images by use of XImportImage, XImportInfo & XGetImportInfo methods. You can examine how these methods work in ImageMagick's source files wand/import.c.
Working Directly with X and Pixel Iterator
MagickWand also includes PixelWand; which, can iterate over an image-pointer in memory. A little more work, but greater flexibility.
#include <stdio.h>
#include <wand/MagickWand.h>
#include <X11/Xlib.h>
int main(int argc, char **argv) {
int x,y;
unsigned long pixel;
char hex[128];
// X11 items
Display *display = XOpenDisplay(NULL);
Window root = DefaultRootWindow(display);
XWindowAttributes attr;
XGetWindowAttributes(display, root, &attr);
// MagickWand items
MagickWand *wand = NULL;
PixelWand *pwand = NULL;
PixelIterator *pitr = NULL;
PixelWand **wand_pixels = NULL;
// Set-up Wand
MagickWandGenesis();
pwand = NewPixelWand();
PixelSetColor(pwand,"white"); // Set default;
wand = NewMagickWand();
MagickNewImage(wand,attr.width,attr.height,pwand);
pitr = NewPixelIterator(wand);
// Get image from display server
XImage *image = XGetImage(display,root, 0,0 ,
attr.width, attr.height,
XAllPlanes(), ZPixmap);
unsigned long nwands; // May also be size_t
for (y=0; y < image->height; y++) {
wand_pixels=PixelGetNextIteratorRow(pitr,&nwands);
for ( x=0; x < image->width; x++) {
pixel = XGetPixel(image,x,y);
sprintf(hex, "#%02x%02x%02x",
pixel>>16, // Red
(pixel&0x00ff00)>>8, // Green
pixel&0x0000ff // Blue
);
PixelSetColor(wand_pixels[x],hex);
}
(void) PixelSyncIterator(pitr);
}
// Write to disk
MagickWriteImages(wand,"screen_test.png");
// Clean-Up
XDestroyImage(image);
pitr=DestroyPixelIterator(pitr);
wand=DestroyMagickWand(wand);
MagickWandTerminus();
XCloseDisplay(display);
return 0;
}
Helpful Hints
Ensure that ImageMagick is able to connect to your display system. Try a few import CLI commands to verify your local install is working. This question is a good example.
import -display localhost:0.0 -window root test_out.png
import -display ::0 -window root test_out.png
import -display :0.0 -window root test_out.png
import -display :0 -window root test_out.png
cli program import from imagemagick can take screenshots by running like this:
import -window root screenshot.png
So input image can be specified as file or as -window root
type: import fileName.fileType (Example: import screen.png)
A cross cursor will appear: Click and drag it over the part of the screen you wish to capture (Be sure the terminal window does not cover what you wish to capture)

MagickWand for C: Lack of documentation means more errors for me

I am writing an improved Perlin noise (I don't really understand simplex noise) terrain generator for C, and I am practically finished with the alpha build. However, there is one thing holding me back: actually saving the stupid image. I recruited MagickWand to help me solve the problem of PNG creation, and it looks like a nice implementation on the whole, with tons of useful features etc., but there is very little documentation on the whole thing. No tutorials, really, just a bunch of lists of functions and some example programs. Here is my code so far, based on this:
EDIT: Cut out a bunch of irrelevant code.
#include <stdio.h>
#include <stdlib.h>
#include "mt.h"
#include "diamondsquare.h"
#include "/Library/Frameworks/libWand.framework/Versions/6.3.0/Headers/wand/MagickWand.h"
int main () {
unsigned long seed = 0, x = 0, y = 0, initial = 0, range = 0;
int smooth = 0, fail = 1, index1 = 0, index2 = 0, exception = 0;
char flagchar1 = 'n';
// Some imperative code. Not relevant.
image *ConstituteImage(x, y, "I", IntegerPixel, grid, &exception);
write("image.png", image);
}
At the very least, I know that this is linked wrong (compiling returns an error inside wand.h that it can't find one of the headers). What's the proper way to go about creating an image from an array within a program using MagickWand for C?
Too much code, it could be summarized with:
image *ConstituteImage(x, y, "I", IntegerPixel, grid, &exception);
write("image.png", image);
But reading the MagickWand link you provided:
MagickWriteImageFile
MagickWriteImageFile() writes an image to an open file descriptor. The
format of the MagickWriteImageFile method is:
MagickBooleanType MagickWriteImageFile ( MagickWand *wand, FILE *file
); A description of each parameter follows:
wand: The magick wand. file: The file descriptor.
So it is clear you have to call:
MagickBooleanType MagickWriteImageFile ( MagickWand *wand, FILE *file );
that header almost definitely tries to include other headers so you need something like:
gcc -I"/Library/Frameworks/libWand.framework/Versions/6.3.0/Headers"
or
gcc -I"/Library/Frameworks/libWand.framework/Versions/6.3.0/Headers/wand"

ASN1_INTEGER to ASN1_STRING

I am using openssl to get data about x509 certificate.
Is there a way to convert ASN1_INTEGER to ASN1_STRING, which can than easily be transformed to char array? Is there a way to convert it to any other human readable format?
EDIT: I'm using openssl compiled for iOS, as I am having the iOS project. Here is the code I am using to extract the serial number from the certificate:
ASN1_INTEGER *serial = X509_get_serialNumber(certificateX509);
long value = ASN1_INTEGER_get(serial);
NSLog(#"Serial %ld", value);
certificateX509 is a valid X509 object and I have managed to get some other fields from it (issuer name, expiry date and so on)
EDIT 2:
I finally came to a solution, which may not be the most straightforward one:
ASN1_INTEGER *serial = X509_get_serialNumber(certificateX509);
BIGNUM *bnser = ASN1_INTEGER_to_BN(serial, NULL);
int n = BN_num_bytes(bnser);
unsigned char outbuf[n];
int bin = BN_bn2bin(bnser, outbuf);
char *hexbuf = (char*) outbuf;
hexBuf then contains characters whose value needs to be read as hex integer in order to retrieve logical values.
I use NSMutableString to create a human readable string:
NSMutableString *str = [[NSMutableString alloc] init];
for (int i=0; i<n; i++) {
NSString *temp = [NSString stringWithFormat:#"%.6x", hexbuf[i]];
[str appendString:[NSString stringWithFormat:#"%# ", temp]];
}
If there is a simpler way, I would really like to know it.
The ascii hex conversion be done more simply using the built in BN_bn2hex(BIGNUM *) function
ASN1_INTEGER *serial = X509_get_serialNumber(certificateX509);
BIGNUM *bnser = ASN1_INTEGER_to_BN(serial, NULL);
char *asciiHex = BN_bn2hex(bnser);
One possibility is that you can extract the value of the ASN1_INTEGER as a normal C integer:
#include <openssl/asn1.h>
#include <stdio.h>
int main(int argc, char** argv) {
long value;
ASN1_INTEGER asn1int = {0};
ASN1_INTEGER_set(&asn1int, 42);
value = ASN1_INTEGER_get(&asn1int);
printf("The value is %ld.\n", value);
return 0;
}
Compiled like this:
gcc -Wall -o sploots sploots.c -lcrypto
this produces the output:
The value is 42.
To have the value as a string in an array of char, use snprintf.
I suspect there are also possibilities for using the BIO printing routines to dump the value to a BIO of some sort (perhaps a memory BIO). However, this approach seems simpler.
The way I arrived at this answer is that I looked through the OpenSSL headers for ASN1_INTEGER. After looking around for suitable APIs for a BIO-based solution, I noticed the ASN1_INTEGER_get function.
Looking around in OpenSSL header files is typically the way I learn how to use OpenSSL, since so much of the API is undocumented or incorrectly or incompletely documented.
I finally came to a solution, which may not be the most straightforward one:
ASN1_INTEGER *serial = X509_get_serialNumber(certificateX509);
BIGNUM *bnser = ASN1_INTEGER_to_BN(serial, NULL);
int n = BN_num_bytes(bnser);
unsigned char outbuf[n];
int bin = BN_bn2bin(bnser, outbuf);
char *hexBuf = (char*) outbuf;
hexBuf then contains characters whose value needs to be read as hex integer in order to retrieve logical values.
I use NSMutableString to create a human readable string:
NSMutableString *str = [[NSMutableString alloc] init];
for (int i=0; i<n; i++) {
NSString *temp = [NSString stringWithFormat:#"%.6x", hexbuf[i]];
[str appendString:[NSString stringWithFormat:#"%# ", temp]];
}
If you just want a readable NSString, BN_bn2dec is more consize than BN_bn2hex or BN_bn2bin.
No need to mess with hex encoding.
Here's my way, in iOS/ObjC, using pod 'OpenSSL-Universal', '1.0.2.10' :
ASN1_INTEGER *serialAsn1 = X509_get_serialNumber(certX509);
BIGNUM *serialBigNumber = ASN1_INTEGER_to_BN(serialAsn1, NULL);
char *serialChar = BN_bn2dec(serialBigNumber);
NSString *serialString = [NSString stringWithCString:(const char *) serialChar
encoding:NSUTF8StringEncoding];
Cheers.
This solution worked for me to get the serial number in hex:
ASN1_INTEGER* serial = X509_get_serialNumber(X509_certificate_ptr);
BIGNUM* bn = ASN1_INTEGER_to_BN(serial, NULL);
if (!bn) {
// log here "Unable to convert ASN1INTEGER to BN";
return "";
}
char* hex = BN_bn2hex(bn);
if (!hex) {
// Log here "Unable to convert BN to hex string";
return "";
}
cout << hex; // this is your serial number. Can be converted using std::to_string()
BN_free(bn);
ASN1_INTEGER_free(serial);
OPENSSL_free(hex);
return serial_number;
Without error checking and memory management the code is basically:
ASN1_INTEGER* serial = X509_get_serialNumber(X509_certificate_ptr);
BIGNUM* bn = ASN1_INTEGER_to_BN(serial, NULL);
char* hex = BN_bn2hex(bn);

Resources