Tile or montage in MagickWand

The MagickWand interface is a new high-level C API interface to ImageMagick core methods. We discourage the use of the core methods and encourage the use of this API instead. Post MagickWand questions, bug reports, and suggestions to this forum.
Post Reply
rpatelob
Posts: 62
Joined: 2017-04-17T22:17:01-07:00
Authentication code: 1151

Tile or montage in MagickWand

Post by rpatelob » 2017-04-21T05:41:10-07:00

Hello snibgo, could you help me with MagickMontageImage?

Code: Select all

convert tileC.jpg -write mpr:tile -size 1200x874 tile:mpr:tile tileCmpr.jpg
I have this command, it takes 8x8 source image and generate a tile image.

For that I wrote below code. But it takes too much time. I get the expected image but code is not well written. Could you please give me suggestion in it?

Code: Select all

  
temp_wend = CloneMagickWand(wandG4);
for (size_t i = 0; i <= 20000; i++) {
      MagickReadImage(temp_wend, "tileC.jpg");
      MagickSetLastIterator(temp_wend);
}
wandG5 = MagickMontageImage(temp_wend, dw, "150x110+0+0", "8x8+0+0",UndefinedMode,"0x0+0+0");
MagickWriteImage(wandG5, "tileP11.jpg");

snibgo
Posts: 9490
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: append images vertically using MagickWand C API.

Post by snibgo » 2017-04-21T06:23:18-07:00

As this is a new question, I have started a new thread for it.

You are reading the same file 20,000 times. If you really want 20,000 images, cloning will be faster than reading files. (I don't use Wand, but MagickAddImage() seems useful.)

I assume tileC.jpg is 8x8 pixels. So perhaps using NULL for thumbnail_geometry will be faster.

Also, perhaps using NULL for frame will be faster.

But I don't understand why you want 20,000 images, montaged together. Can't you simply read "tile:tileC.jpg"?
snibgo's IM pages: im.snibgo.com

rpatelob
Posts: 62
Joined: 2017-04-17T22:17:01-07:00
Authentication code: 1151

Re: Tile or montage in MagickWand

Post by rpatelob » 2017-04-21T07:22:26-07:00

Source Image(8x8)
https://drive.google.com/file/d/0B-HZjm ... sp=sharing
Final Image
https://drive.google.com/file/d/0B-HZjm ... sp=sharing

Check above two links, I have provided the images. I have a source image of 8x8 and I want the final result like second image. So I read source image multiple time and create a tile image. And as you have mentioned that simply create a tile image using "tile:tileC.jpg", you means MagickReadImage(wand, "tile:tileC.jpg"); this way?

el_supremo
Posts: 1017
Joined: 2005-03-21T21:16:57-07:00

Re: Tile or montage in MagickWand

Post by el_supremo » 2017-04-21T09:19:45-07:00

Try MagickTextureImage:
% MagickTextureImage() repeatedly tiles the texture image across and down the
% image canvas.
%
% The format of the MagickTextureImage method is:
%
% MagickWand *MagickTextureImage(MagickWand *wand,
% const MagickWand *texture_wand)
%
% A description of each parameter follows:
%
% o wand: the magick wand.
%
% o texture_wand: the texture wand
I haven't tried it but it seems to do what you want. texture_wand will be tileC.jpg and wand will be a blank canvas of the required size.

Pete
Sorry, my ISP shutdown all personal webspace so my MagickWand Examples in C is offline.
See my message in this topic for a link to a zip of all the files.

el_supremo
Posts: 1017
Joined: 2005-03-21T21:16:57-07:00

Re: Tile or montage in MagickWand

Post by el_supremo » 2017-04-21T09:50:25-07:00

Got it working with this code:

Code: Select all

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <wand/magick_wand.h>

void test_wand(void)
{
	MagickWand *wand, *texture_wand, *output_wand;

	MagickWandGenesis();

	wand = NewMagickWand();
	MagickSetSize(wand,1200,874);
	MagickReadImage(wand,"xc:white");

	texture_wand = NewMagickWand();
	MagickReadImage(texture_wand, "tileC.jpg");

	output_wand = MagickTextureImage(wand,texture_wand);
	if(output_wand == NULL) {
		MessageBox(NULL,"MagickTextureImage returned NULL!","",MB_OK);
		wand = DestroyMagickWand(wand);
		texture_wand = DestroyMagickWand(texture_wand);
		MagickWandTerminus();
		return;
	}

	MagickWriteImage(output_wand,"tileP11.jpg");

	/* Clean up */
	DestroyMagickWand(wand);
	DestroyMagickWand(texture_wand);
	DestroyMagickWand(output_wand);
	MagickWandTerminus();

}
A couple of notes:
- the tile doesn't fit exactly in 1200x874.
- I specifically test that MagickTextureImage returns a valid pointer. I first tried this without "MagickReadImage(wand,"xc:white");" and it returned NULL. Don't know why that makes a difference.

Pete
Sorry, my ISP shutdown all personal webspace so my MagickWand Examples in C is offline.
See my message in this topic for a link to a zip of all the files.

el_supremo
Posts: 1017
Joined: 2005-03-21T21:16:57-07:00

Re: Tile or montage in MagickWand

Post by el_supremo » 2017-04-21T10:29:33-07:00

P.S. I compiled the example with ImageMagick 6.9.7-10 Q16 x64.

Pete
Sorry, my ISP shutdown all personal webspace so my MagickWand Examples in C is offline.
See my message in this topic for a link to a zip of all the files.

rpatelob
Posts: 62
Joined: 2017-04-17T22:17:01-07:00
Authentication code: 1151

Re: Tile or montage in MagickWand

Post by rpatelob » 2017-04-23T21:27:27-07:00

el_supremo wrote:
2017-04-21T09:50:25-07:00
Got it working with this code:

Code: Select all

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <wand/magick_wand.h>

void test_wand(void)
{
	MagickWand *wand, *texture_wand, *output_wand;

	MagickWandGenesis();

	wand = NewMagickWand();
	MagickSetSize(wand,1200,874);
	MagickReadImage(wand,"xc:white");

	texture_wand = NewMagickWand();
	MagickReadImage(texture_wand, "tileC.jpg");

	output_wand = MagickTextureImage(wand,texture_wand);
	if(output_wand == NULL) {
		MessageBox(NULL,"MagickTextureImage returned NULL!","",MB_OK);
		wand = DestroyMagickWand(wand);
		texture_wand = DestroyMagickWand(texture_wand);
		MagickWandTerminus();
		return;
	}

	MagickWriteImage(output_wand,"tileP11.jpg");

	/* Clean up */
	DestroyMagickWand(wand);
	DestroyMagickWand(texture_wand);
	DestroyMagickWand(output_wand);
	MagickWandTerminus();

}
A couple of notes:
- the tile doesn't fit exactly in 1200x874.
- I specifically test that MagickTextureImage returns a valid pointer. I first tried this without "MagickReadImage(wand,"xc:white");" and it returned NULL. Don't know why that makes a difference.

Pete
This is working for me. Thank you el_supremo.
Version: ImageMagick 7.0.5-4 Q16 x86_64 2017-03-28 http://www.imagemagick.org

Post Reply