Creating a mosaic with gflMerge

Discussions on GFL SDK, the graphic library for reading and writing graphic files

Moderators: XnTriq, helmut, xnview

Melk
Posts: 4
Joined: Tue Sep 15, 2009 9:20 am

Creating a mosaic with gflMerge

Post by Melk »

I'm quite new to GFL SDK (commercial license) and i'm trying to create a mosaic from several images that have the same sizes.

The problem I encounter is that my mosaic won't be at the good size (that is (originalWidth * 2, originalHeight * 4) ) after the use of gflMerge.

Here is my code:

Code: Select all

GFL_BITMAP* CImageBMP::mergeImages(const GFL_BITMAP *images[], const int nb_images = 8)
{
    GFL_BITMAP* final_image = new GFL_BITMAP;
    
    int width = images[0]->Width,
        height = images[0]->Height;

    //Just 8 images for the moment.
    final_image->Width = width * 2;
    final_image->Height = height * 4;

    GFL_POINT origin[] = { 
        {width * 0, height * 0}, {width * 1, height * 0}, 
        {width * 0, height * 1}, {width * 1, height * 1},
        {width * 0, height * 2}, {width * 1, height * 2},
        {width * 0, height * 3}, {width * 1, height * 3} 
    };

    GFL_UINT32 opacity[] = {255, 255, 255, 255, 255, 255, 255, 255};

    gflMerge(images, origin, opacity, nb_images, &final_image);

    return final_image;
}
At this point, with 320x240 source images, my final image is also 320x240 sized, instead of 640x960.
Should I resize the source pictures to the final size and then merge them altogether, or am I misusing the function?

Thanks.
mhammann
Posts: 5
Joined: Tue Sep 15, 2009 1:42 pm

Re: Creating a mosaic with gflMerge

Post by mhammann »

Hello Melk,

I have the same problem.

gflMerge is allocating a GFL_BITMAP structure for the merged image and I didn't manage to resize its dimension.
In addition, size and content of the merged image is similar to the first image of my GFL_BITMAP array.

Does anyone have an idea how gflMerge function works ?

Michel
User avatar
xnview
Author of XnView
Posts: 44304
Joined: Mon Oct 13, 2003 7:31 am
Location: France

Re: Creating a mosaic with gflMerge

Post by xnview »

mhammann wrote: Does anyone have an idea how gflMerge function works ?
Currently gflMerge use the size of the first picture, and allocate it
Pierre.
Melk
Posts: 4
Joined: Tue Sep 15, 2009 9:20 am

Re: Creating a mosaic with gflMerge

Post by Melk »

Thanks for your reply.

So I suppose the solution would be to have the final image as a canvas at first position in the array of images, and add the others on top of it?

Edit: Ok I have the good size now. I had to create a new image as a copy of one of my base images, then gflResize it, and use it as my first image in the array with a 0 for Opacity. Seems to Work. (I cannot see the result for now because of another problem ;) )
mhammann
Posts: 5
Joined: Tue Sep 15, 2009 1:42 pm

Re: Creating a mosaic with gflMerge

Post by mhammann »

Do all images require an alpha channel with the value set to the opacity value used for gflMerge ?

Thanks,

Michel
Melk
Posts: 4
Joined: Tue Sep 15, 2009 9:20 am

Re: Creating a mosaic with gflMerge

Post by Melk »

@Michel: According to the doc, gflMerge() only works for 24 & 32bits images. So you should not have to set an alpha channel on your images.
Still, I have the same problem as you, that is, I cannot have anything but the first mage of my array as a result of gflMerge().
I will try some few things, and hopefully come up with a solution.
mhammann
Posts: 5
Joined: Tue Sep 15, 2009 1:42 pm

Re: Creating a mosaic with gflMerge

Post by mhammann »

Dear Melk,

Thank you for your feedback.
On my side, I didn't point out any solution.
Images with alpha channel causes allocation error with gflMerge.
In addition, I've tested several image order/combination and it delivers the same result -> first image dimension and data for the merged image !

Hope you will have more chance with your test.

Michel
User avatar
xnview
Author of XnView
Posts: 44304
Joined: Mon Oct 13, 2003 7:31 am
Location: France

Re: Creating a mosaic with gflMerge

Post by xnview »

Could you send me pictures, source & result wanted?
Pierre.
mhammann
Posts: 5
Joined: Tue Sep 15, 2009 1:42 pm

Re: Creating a mosaic with gflMerge

Post by mhammann »

Dear all,

My objective is to use gflMerge image to create a mosaic of images of different size placed at precomputed position in the mosaic.
For the test below, I don't take this constraint into consideration.

Nature and type of the images are always the same.

Please find my code hereinafter.

Code: Select all

	// Get the value parsed by each arg. 
	std::string outputFilename = outputFile.getValue();
	std::vector<string> inputFilenames = inputFiles.getValue();
	int nFilenamesToMerge = inputFilenames.size();

	GFL_LOAD_PARAMS load_option; 
	GFL_FILE_INFORMATION file_info; 
	GFL_ERROR error; 

	gflSetPluginsPathname("..\\plugins\\"); 
	gflLibraryInit(); 
	gflEnableLZW( GFL_TRUE ); 

	gflGetDefaultLoadParams( &load_option ); 

	const GFL_BITMAP* bitmap_table[3];
	GFL_BITMAP* merged_bitmap = 0;
	GFL_UINT32 opacity[3] = { 128, 128, 128 }; 
	GFL_POINT points[3] = { {0, 0}, {0, 0}, {0, 0}}; 

	GFL_SAVE_PARAMS save_option;
	GFL_INT32 i;

	for (i=0; i< nFilenamesToMerge; i++)
		{
			std::string sFilenameToLoad = inputFilenames[i];

			// Load bitmap
			error = gflLoadBitmap( sFilenameToLoad.c_str(),(GFL_BITMAP**) &bitmap_table[i], &load_option, &file_info );
			
			if ( error != GFL_NO_ERROR)
			  throw error;

			// Just verify the validity of each image that has been loaded previously
			gflGetDefaultSaveParams( &save_option ); 

			save_option.Flags = GFL_SAVE_REPLACE_EXTENSION; 
			save_option.FormatIndex = file_info.FormatIndex; 

			std::string sFilename = sFilenameToLoad + "_backup.png";
			error = gflSaveBitmap( (char*)sFilename.c_str(), bitmap_table[i], &save_option ); 

			if ( error != GFL_NO_ERROR)
			  throw error;
		}

	// Merge all images into a single one
	error = gflMerge(bitmap_table, 
			points, 
			opacity, 
			(GFL_INT32)nFilenamesToMerge, 
			(GFL_BITMAP**)&merged_bitmap ); 

	if ( error != GFL_NO_ERROR)
	  throw error;

	// Save merged image
	gflGetDefaultSaveParams( &save_option ); 

	save_option.Flags = GFL_SAVE_REPLACE_EXTENSION; 
	save_option.FormatIndex = file_info.FormatIndex; 

	error = gflSaveBitmap( (char*)outputFilename.c_str(), merged_bitmap, &save_option ); 

	if ( error != GFL_NO_ERROR)
	  throw error;

	// Free memory allocated for the operation
	gflFreeBitmap( merged_bitmap ); 
	for (i=0; i<nFilenamesToMerge; i++)
		{
			gflFreeBitmap( (GFL_BITMAP*)bitmap_table[i] ); 
		}
	gflLibraryExit(); 
Intermediate saved images are fine, but not the final merged image.

Herein attached 3 images used for merge operation and the final result test.png.

Thanks for your help,

Michel
You do not have the required permissions to view the files attached to this post.
mhammann
Posts: 5
Joined: Tue Sep 15, 2009 1:42 pm

Re: Creating a mosaic with gflMerge

Post by mhammann »

Dear Melk,

I've worked around the problem using a different method.
See the headlines following :
- create a new image using gflAllockBitmapEx with the desired dimension
- for each image to merge, copy pixel per pixel all pixels coming from the source image to the destination image at the right position using gflGetColorAt and gflSetColorAt functions.
- save the destination image

This is 'the old fashion' method to merge images but it works fine for images with same specifications (type, bit per component, etc).
Kind regards,

Michel
Melk
Posts: 4
Joined: Tue Sep 15, 2009 9:20 am

Re: Creating a mosaic with gflMerge

Post by Melk »

Thank you Michel,

I still wish I could use gflMerge, since it looked very handy, but unfortunately work has to continue. Thanks again for the 'old-fashion' way of solving our problem!

Regards
User avatar
dominique
Posts: 72
Joined: Thu Nov 08, 2007 9:22 am

Re: Creating a mosaic with gflMerge

Post by dominique »

I tested the exemple you give and got no result.
I do some visible watermarking with gfl and I use gflBitblt/gflBitbltEx instead of pixel per pixel copy.
I guess gflMerge is built on this functions.

Edit : I 've juste done other tests and got something interesting
Try to use opacity between 0 and 100 and use different origine. You should see your images merged.

Edit 2 :

Code: Select all

GFL_UINT32 opacity[3] = { 10, 50, 100 };
GFL_POINT points[3] = { {0, 0}, {0, 0}, {0, 0}};
Dom