Welcome Guest! You need to login or register to make posts.

Notification

Icon
Error

Options
Go to last post Go to first unread
flluidmedia  
#1 Posted : Friday, May 14, 2004 3:58:00 AM(UTC)
flluidmedia

Rank: Member

Groups: Member
Joined: 4/27/2004(UTC)
Posts: 40

I'm looking for any information at all about how to speed things up when using Graphics Mill. I want to cut as many corners as possible in my application. Has anyone found anything in particular that really helps speed things up?

For my own program, I follow these steps:

1. Create a bitmap object copy a number of smaller tiles on to it
2. Use the bitmap from 1 as a brush to paint a larger bitmap
3. Convert the bmp from 2 into an aurigma bitmap
4. Use the projective points function (inline)
5. Apply a rotation (inline)
6. Load a new aurigma bmp with a background image
7. Load a new aurigma bmp with a mask image
8. Apply the mask to the image from 5
9. Draw it onto the background image
10. Response.Write the final image out

I'm working c# under .net 1.1

Thanks,
Brian
Andrew  
#2 Posted : Friday, May 14, 2004 1:43:00 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 866

Thanks: 2 times
Was thanked: 26 time(s) in 26 post(s)
Hi Brian,


1. Create a bitmap object copy a number of smaller tiles on to it
2. Use the bitmap from 1 as a brush to paint a larger bitmap


If you use the same bitmap for tiles, draw attention to Texturize method of Graphics Mill's bitmap.


3. Convert the bmp from 2 into an aurigma bitmap


By the way, View post (an example of efficient way to convert GDI+ bitmap to Graphics Mill and vice versa).


4. Use the projective points function (inline)
5. Apply a rotation (inline)


These operations can be united. Rotation is a special case of affine transform (which is a special case of projective transform ;) ). Using some math we can calculate a matrix which can be used to perform distortion + rotation at single ProjectiveMatrix function call.

Do you use the same projective points or calculate them from some parameters?


6. Load a new aurigma bmp with a background image
7. Load a new aurigma bmp with a mask image
8. Apply the mask to the image from 5
9. Draw it onto the background image


Are the background/mask images predefined or user upload them? If you define masks/backgrounds yourself, you can make sure if they are already in proper pixel format (either do it in photoshop beforehand, or make special script which prepares backgrounds and masks).


10. Response.Write the final image out


By the way, if bitmap from step 1 does not depend on user input (you store such bitmaps on server), you could avoid performing these operations on-the-fly. This way you do the operations on server once, save the result to disk, and send it to user when requested.
flluidmedia  
#3 Posted : Thursday, June 10, 2004 10:39:00 PM(UTC)
flluidmedia

Rank: Member

Groups: Member
Joined: 4/27/2004(UTC)
Posts: 40

Wow - that is some great information.

For 1, 2 & 3 - The bitmap that is used to paint the larger bitmap is dynamic. It gets built from smaller tiles that the user specifies at run time.

For 4 & 5 - I don't know how to build a matrix to do the tranformation. Are there any resources available for doing this?. The projective points are always the same for a given sceen.

Part of the images are determined at run time and the others are static. The scenes are static, but what I am masking into them is defined by the user at run time.

Thanks again!
Brian
Andrew  
#4 Posted : Friday, June 11, 2004 1:48:00 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 866

Thanks: 2 times
Was thanked: 26 time(s) in 26 post(s)
Hi Brian,

The projective points transformation can be represented via projective matrix. Then you multiply it on rotation matrix, and pass result to ProjectiveMatrix.

All these algorithms are the part of linear algebra, so you could search for materials concerning it. Besides you can post here (or submit case) parameters of your projective points transform and rotation angle and we will describe these algorithms at your example.

Edited by user Friday, May 23, 2008 4:01:39 PM(UTC)  | Reason: Not specified

flluidmedia  
#5 Posted : Monday, June 14, 2004 11:51:00 PM(UTC)
flluidmedia

Rank: Member

Groups: Member
Joined: 4/27/2004(UTC)
Posts: 40

I know a bit about using matrices to do scaling, transformation and rotation but what I don't know is how to do a non-affine transformation. My searches on the net havent turned up a lot in that regard.

After I apply the transformation to my image (foreground), I need to mask into another image. Its no longer the same size as the background and mask images. Currently I create a new bitmap, of the correct size, and copy the transformed image unto it. Would it be faster to resize the transformed image? Or is this just as expensive from a processing point of view. Could this be accomplished the projective matrix as well?


I have an image, which is (0,0,1386,1386). I apply the following transformation to the image dest: (0,200,300,-890,32,1386,600,50) - src: (0,0,1386,0,0,1386,1386,1386). I then rotate this image 90 degrees clockwise.

Thanks!

Brian,
Fluid Media
Andrew  
#6 Posted : Tuesday, June 15, 2004 2:37:00 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 866

Thanks: 2 times
Was thanked: 26 time(s) in 26 post(s)
Non-affine transformations are made in the similar way as affine ones, but they use larger matrix. To build such matrix from points, we should construct system of linear equations and calculate its coefficients. If you like, I could describe how to do it.

However fortunately there is an easier way. We can just each point on rotation matrix and use ProjectivePoints method instead of ProjectiveMatrix. Moreover, as you rotate on 90 degrees, it becomes much simplier - you even can do no calculations, but just rearrange parameters of ProjectivePoints.

Rotation matrix is

Code:

| cos(a)  sin(a) |
|                |
| -sin(a) cos(a) |


Argument a is a counter-clockwise angle there. You are rotating 90 degrees clockwise, so in our case a = -90. Let's calculate that:

Code:

| cos(-90)  sin(-90) |     | 0   -1 |
|                    |  =  |        |
| -sin(-90) cos(-90) |     | 1    0 |


As you see, transformation is extremely simple:

Code:

| 0   -1 |       |  x  |     |  -y  |
|        |   *   |     |  =  |      |
| 1    0 |       |  y  |     |   x  |


In other word you should just swap x and y and change sign of y. In other words, instead of

Code:

objBitmap.Transforms.ProjectivePoints 0, 200, 300, -890, 32, 1386, 600, 50, _
				      0, 0,  1386, 0, 0, 1386, 1386, 1386	


use this code:

Code:

objBitmap.Transforms.ProjectivePoints -200, 0, 890, 300, -1386, 32, -50, 600, _
				      0, 0,  1386, 0, 0, 1386, 1386, 1386


It will be equivalent to calling Rotate method with angle argument = 90.

Please let me know if you have any questions with it.

Edited by user Monday, December 24, 2007 5:23:50 PM(UTC)  | Reason: Not specified

flluidmedia  
#7 Posted : Tuesday, June 15, 2004 11:07:00 PM(UTC)
flluidmedia

Rank: Member

Groups: Member
Joined: 4/27/2004(UTC)
Posts: 40


Wow - that is great!

Is there any advantage to using the matrix over the points or does it amount to same thing? I'm trying cut as many corners as I can with this since it will be running on a web server that may see a fair bit of traffic. Manipulating a bunch of high quality images may start to bog the server down so I want to make it efficient as possible.

Is there any difference, computationally, between doing a copy to a new image or resizing the existing image (see previous post for more details)?

Thanks again! The support on this board and by this company is outstanding!

Brian
Fluid Media
Andrew  
#8 Posted : Wednesday, June 16, 2004 4:40:00 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 866

Thanks: 2 times
Was thanked: 26 time(s) in 26 post(s)
> Is there any advantage to using the matrix over the points or does it amount to same thing? I'm trying cut as many corners as I can with this since it will be running on a web server that may see a fair bit of traffic. Manipulating a bunch of high quality images may start to bog the server down so I want to make it efficient as possible.


No, ProjectiveMatrix and ProjectivePoints are equivalent. ProjectivePoints converts points into matrix inside, and call ProjectiveMatrix method, but additional work is too tiny comparing to the transformation itself and does not worth to take it into account.

> Is there any difference, computationally, between doing a copy to a new image or resizing the existing image (see previous post for more details)?

I have posted a C# sample demonstrating how to get Graphics Mill Bitmap from GDI+.

> Thanks again! The support on this board and by this company is outstanding!

I am happy that you think so! :)
flluidmedia  
#9 Posted : Thursday, June 17, 2004 2:40:00 AM(UTC)
flluidmedia

Rank: Member

Groups: Member
Joined: 4/27/2004(UTC)
Posts: 40

> Is there any difference, computationally, between doing a copy to a new image or resizing the existing image (see previous post for more details)?

This is actually about another step, not the conversion from gdi+ to GM.

After I transform my image (a GM bmp), I need to mask it onto a background. However, its not the right size to do this ( they have to be the same size, right?). So I create a new blank GM bmp of the correct dimensions and then copy the transformed image onto that at the x,y offset that I need.

I know that there is a resize feature available in GM but is it any faster to use it than to create a new GM bitmap?

Thanks!
Brian
Fluid Media
Andrew  
#10 Posted : Thursday, June 17, 2004 1:37:00 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 866

Thanks: 2 times
Was thanked: 26 time(s) in 26 post(s)
Of course resize works slower than creating empty bitmap and copying image to it (or using outer crop). However the result is also different, so if you will use cropping instead of resizing, you can get not what you want.

By the way, if all sizes are fixed, it is possible you can combine resize with ProjectivePoints too. For example if you always apply the transform mentioned above on the image 1386x1386, you will also have result image 2274x599. Let's assume that you want to resize it to fit, say 800x211. To get scale factor, just divide destination image dimensions on source image dimensions:

horizontal factor = 800/2274 ~ 0.35
vertical factor = 211/599 ~ 0.35

I have especially choosen such values to make resize proportional, however if is not important to you, you can use different resize factors.

To make ProjectivePoints resize the image, we should use transform matrix again. Scaling matrix is looking in the following way:

Code:

| a  0 |
|      |
| 0  b |


where a is a horizontal scale factor, b is a vertical scale factor. Again, multiply this matrix on each point:

Code:

| a  0 |   | x |   | a*x |
|      | * |   | = |     |
| 0  b |   | y |   | b*y |


In other word, you should just multiply x-coordinate on horizontal factor, and y-coordinate on vertical factor. This way the ProjectivePoints call should look something like that:

Code:
long srcWidth, srcHeight, destWidth, destHeight;

srcWidth = 2274;
srcHeight = 599;

// You can get these sizes from actual image instead of hardcoding.
destWidth = 800;    
destHeight = 211;

double horScale, vertScale;
horScale = destWidth / srcWidth;
vertScale = destHeight / srcHeight;

bitmap.Transforms.ProjectivePoints(-200 * horScale, 0 /* no need to scale 0 :) */ ,
                                    890 * horScale, 300 * vertScale, 
				  -1386 * horScale, 32 * vertScale, 
				    -50 * horScale, 600 * vertScale,
				     0, 0,  1386, 0, 0, 1386, 1386, 1386,
					0xFFFFFFFF, 1, 1);


This way you get the transformed image of correct size and proceed with blending it with background without additional steps.

Edited by user Monday, December 24, 2007 5:24:09 PM(UTC)  | Reason: Not specified

flluidmedia  
#11 Posted : Thursday, June 17, 2004 11:22:00 PM(UTC)
flluidmedia

Rank: Member

Groups: Member
Joined: 4/27/2004(UTC)
Posts: 40

That is very interesting. I wonder if we can take it a step further? I'm not actually resizing the image that I have transformed but rather copying it to another bitmap which is the same size as the mask.

To continue with the above example:

I have the transformed image, which is gmFloor (0,0,2274,599). I also have a room image, gmRoom (0,0,935,625) and a mask, gmMask, which is the same size as gmRoom.

What I am doing now, is creating a new image, gmFront(0,0,935,625), and copying the transformed image, gmFloor, onto it at an x,y offset of (-455,459).

Code:
// draw the floor onto it at the x, y offset from the rooms.xml file
gmFloor.DrawOnBitmap( gmFront, int.Parse(arrParams[0]), int.Parse(arrParams[1]), gmFloor.Width, gmFloor.Height, 0, 0, gmFloor.Width, gmFloor.Height, 
Aurigma.GraphicsMill.CombineMode.CombineModeCopy, 255, Aurigma.GraphicsMill.InterpolationMode.InterpolationModeHighSpeed, true, true, true);


Where arrParams[0] and [1] are the required x and y offsets.

This crops the transformed image, pastes it in at the correct spot, in the correct size to use the mask.

Could I combine a translation matrix into the projective points and then do an outer crop on gmFloor and avoid having to create gmFloor entirely?

Thanks again!
Brian
Fluid Media

Edited by user Monday, December 24, 2007 5:24:23 PM(UTC)  | Reason: Not specified

Andrew  
#12 Posted : Friday, June 18, 2004 12:39:00 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 866

Thanks: 2 times
Was thanked: 26 time(s) in 26 post(s)
Well... Why not to use Crop method instead of DrawOnBitmap?

Code:
int x, y, width, height;
x = int.Parse(arrParams[0]);
y = int.Parse(arrParams[1]);
width = gmRoom.Data.Width;  // width of target image
height = gmRoom.Data.Height; // height of target image
gmFloor.Transforms.Crop(x, y, width, height, 0x00FFFFFF);


After that gmFloor contains cropped image of necessary size and you need not create intermediate bitmap. It seems to be optimal way.

Edited by user Monday, December 24, 2007 5:24:34 PM(UTC)  | Reason: Not specified

flluidmedia  
#13 Posted : Sunday, June 20, 2004 10:09:00 PM(UTC)
flluidmedia

Rank: Member

Groups: Member
Joined: 4/27/2004(UTC)
Posts: 40


Hmm... hang on a minute - I thought this would work, but it doesn't yield the result that I want.

The x,y is the offset where gmFloor needs to be masked into the final scene, not the offset of the portion to crop. After the transformation, I want to take a portion of gmFloor, say the top right corner, and cut it out to the size of the mask - but that top right corner needs to show up at x,y in the target image. In other words, it doesnt just need to be cropped it has to be moved down the image as well.

here are some images to show what I'm trying to do:

gmFloor, pre transformation:
UserPostedImage

gmFloor, post-transform:
UserPostedImage

gmBack (what is being drawn onto):
UserPostedImage

gmMask (used to crop gmFloor to fit gmBack):
UserPostedImage

Final output:
UserPostedImage

So basically need gmFloor to end up with enough white space at the top of it to make the top right corner fit into the corner of the room after the mask. That is why I was copying on to a new image, which is the size of the mask, at an offset of (x,y)

Brian
Fluid Media
Andrew  
#14 Posted : Sunday, June 20, 2004 10:20:00 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 866

Thanks: 2 times
Was thanked: 26 time(s) in 26 post(s)
If you have other questions, please do not hesitate to ask again.
flluidmedia  
#15 Posted : Sunday, June 20, 2004 11:34:00 PM(UTC)
flluidmedia

Rank: Member

Groups: Member
Joined: 4/27/2004(UTC)
Posts: 40


Sorry, Andrew I was too hasty with my reply... see my previous post... but the support is still awesome!

Brian
Andrew  
#16 Posted : Monday, June 21, 2004 1:02:00 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 866

Thanks: 2 times
Was thanked: 26 time(s) in 26 post(s)
When cropping rectangle is out of the image you crop, blank pixels are added. So if you specify negative x and y, the image will be moved as you want. In the same way you can increase width and height. For example, you need to move image on 100 right and 15 pixels down, use the following arguments:

Code:
gmFloor.Transforms.Crop -100, -15, gmRoom.Data.Width, gmRoom.Data.Height

Edited by user Monday, December 24, 2007 5:24:53 PM(UTC)  | Reason: Not specified

flluidmedia  
#17 Posted : Monday, June 21, 2004 11:55:00 PM(UTC)
flluidmedia

Rank: Member

Groups: Member
Joined: 4/27/2004(UTC)
Posts: 40



Thanks again for the fast response with a great solutions - working great now with many extraneous steps removed.

Keep up the good work!

Brian
Fluid Media
Andrew  
#18 Posted : Tuesday, June 22, 2004 12:38:00 PM(UTC)
Andrew

Rank: Advanced Member

Groups: Member, Administration
Joined: 8/2/2003(UTC)
Posts: 866

Thanks: 2 times
Was thanked: 26 time(s) in 26 post(s)
Happy to know that you get it working in the way you want. Please feel free to post a message if you need any help again.
Users browsing this topic
Similar Topics
Image Optimization (Discussions – Graphics Mill)
by pgoode 4/6/2010 11:30:43 AM(UTC)
Concurrent Upload with Optimization? (Discussions – ActiveX/Java Uploader)
by newvisionjeff 6/14/2007 8:50:49 PM(UTC)
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.