Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
Hi! Glad to see things are moving along nicely for Aurigma.
We bought and used V2 of the graphics mill last year for a project which was a great success. We are now updating and enhancing that project and want to use V3 of the GM. With that in mind, I'm looking for information about what that entails. What is the upgrade process? What chances have been made in V3? Are there any issues that I should be aware of?
I appologize if this information is already available somewhere, I looked around your site, but couldn't find it.
Thanks!!
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
Seems like there are quite a few changes. I'll chronicle my adventures in upgrading for the benefit others. Any help from the Mods would be great!!!
1) BitmapClass on longer exists.
I've substituted this with Bitmap.
2) BitmapClass.SaveToFile doesn't exist in Bitmap
Replaced this with Bitmap.Save(filename)
3) Methods BitmapClass.SaveToMemory doesn't exist in Bitmap
I'm assuming this will need to be replaced with .Save(Stream, IEncoderOptions), but I haven't done this yet.
... more to follow...
|
|
|
|
Rank: Advanced Member
Groups: Guest
Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
Hello Brian,
In fact the Graphics Mill for .NET has completely different API comparing to the ActiveX version. So to migrate you need to rewrite the code which uses Graphics Mill from a scratch.
A bad news is that we did not port the ProjectivePoints/ProjectiveMatrix transform yet (as far as I remember it is quite essential transform in your project). But we will likely include it into some of the nearest update.
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
Ah! That is very bad news.
Looks like I will be abandoning my upgrade saga afterall.
We have an addiontional constraint in that our client doesn't like to install COM components on their server and would prefer a solution (like .net) that doesn't require them to install anything beyound the files in the web folder.
Do you have any suggestions for a solution or possible workaround? Why wasn't the projective functionality upgraded? Some sort of technical difficulty with .NET?
Thanks for letting me know! Brian
|
|
|
|
Rank: Advanced Member
Groups: Guest
Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
In fact we did not include it because we were out of schedule with .NET version release, so we decided to release the first version without this feature. There was not any specific technical problem with it, we just had to freeze the features list, otherwise we would work at it forever... However since this feature is urgent to you, I will discuss it with developers. How urgent is it (you may email to sales@aurigma.com)? Edited by user Friday, May 23, 2008 3:18:36 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
Andrew,
Good 'ole feature creep - I know it well.
I'll discuss with my manager and post an email ASAP on what are our timelines for this project are. Many, many thanks for your excellent support!!!
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
Back to work on this now... First issue I've come across is the lack of SaveToMemory and its solution: OldCode:return (byte[]) Scene.Render(filenameBackground, filenameMask, arrParams, xmlFilename, _product).SaveToMemory();
NewCode:using( MemoryStream ms = new MemoryStream())
{
Scene.Render(filenameBackground, filenameMask, arrParams, xmlFilename, _product).Save(ms, new Aurigma.GraphicsMill.Codecs.BmpEncoderOptions() );
return ms.GetBuffer();
}
Scene.Render(...) is returning a Aurigma.GraphicsMill.Bitmap Edited by user Monday, December 24, 2007 3:30:19 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
How do I add an alpha channel under v3? OldCode:// load image files
gmMask.LoadFromFile( filenameMask ); // must be 8bpp grayscale <---is this still true?
gmBack.LoadFromFile( filenameBackground );
if( ! gmFloor.HasAlphaChannel )
gmFloor.AddAlpha();
gmFloor.Channels.Replace( gmMask, 3 );
NewCode:gmMask.Load( filenameMask );
gmBack.Load( filenameBackground );
if( ! gmFloor.HasAlpha )
gmFloor.Channels.AddAlpha(0);
gmFloor.Channels.Replace( gmMask, 3 ); <--- there is no more replace method
Edited by user Monday, December 24, 2007 3:31:13 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
Think I've found the answer.. Code:gmFloor.Channels[3] = gmMask;
Edited by user Monday, December 24, 2007 3:31:27 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
DrawOnBitmap has been replaced: OldCode:gmFloor.DrawOnBitmap(
gmBack, 0, 0, gmFloor.Width, gmFloor.Height,
0, 0, gmFloor.Width, gmFloor.Height,
Aurigma.GraphicsMill.CombineMode.CombineModeAlpha, 255, Aurigma.GraphicsMill.InterpolationMode.InterpolationModeHighSpeed,
true, true, true);
NewCode:gmFloor.Draw(
gmBack, 0, 0, gmFloor.Width, gmFloor.Height,
0, 0, gmFloor.Width, gmFloor.Height,
Aurigma.GraphicsMill.Transforms.CombineMode.Alpha,
0,
Aurigma.GraphicsMill.Transforms.InterpolationMode.HighSpeed);
note that the location/names of the constants has also changed as well.Edited by user Monday, December 24, 2007 3:31:49 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
This is one is great ( if its right, anyway... ) convert an a gdi+ bitmap to and aurigma bitmap OldCode: [DllImport("kernel32.dll")]
static extern void CopyMemory(IntPtr pDest, IntPtr pSrc, long byteLength);
/// <summary>
/// convert a GDI+ bitmap to an aurigma bitmap
/// </summary>
/// <param name="gdiplusBitmap"></param>
/// <returns></returns>
private static Bitmap GdiplusBitmapToGmBitmap(System.Drawing.Bitmap gdiplusBitmap)
{
// Convert GDI+ pixel format value to Graphics Mill pixel format
PixelFormat pf;
switch (gdiplusBitmap.PixelFormat)
{
case System.Drawing.Imaging.PixelFormat.Format24bppRgb:
pf = PixelFormat.Format24bppRgb;
break;
case System.Drawing.Imaging.PixelFormat.Format32bppArgb:
pf = PixelFormat.Format32bppArgb;
break;
case System.Drawing.Imaging.PixelFormat.Format32bppRgb:
pf = PixelFormat.Format32bppRgb;
break;
case System.Drawing.Imaging.PixelFormat.Format32bppPArgb:
pf = PixelFormat.Format32bppPArgb;
break;
default:
throw new Exception("Incompatible pixel format");
}
// Create new empty bitmap
Aurigma.GraphicsMill.IBitmap gmBitmap = new Aurigma.GraphicsMill.BitmapClass();
gmBitmap.CreateNew(gdiplusBitmap.Width, gdiplusBitmap.Height, pf, Aurigma.GraphicsMill.GraphicsMillConstants.ColorWhite, null);
System.Drawing.Imaging.BitmapData bitmapData;
Rectangle rect = new Rectangle(0, 0, gdiplusBitmap.Width, gdiplusBitmap.Height);
bitmapData = gdiplusBitmap.LockBits(rect, ImageLockMode.ReadOnly, gdiplusBitmap.PixelFormat);
CopyMemory(new IntPtr(gmBitmap.Data.Scan0), bitmapData.Scan0, bitmapData.Stride * bitmapData.Height);
gdiplusBitmap.UnlockBits(bitmapData);
return gmBitmap;
}
NewCode:gmFloor = (Bitmap)bmpFloor;
Edited by user Monday, December 24, 2007 3:33:43 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Advanced Member
Groups: Guest
Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
Hi Brian, In regard to this: NewCode:using( MemoryStream ms = new MemoryStream())
{
Scene.Render(filenameBackground, filenameMask, arrParams, xmlFilename, _product).Save(ms, new Aurigma.GraphicsMill.Codecs.BmpEncoderOptions() );
return ms.GetBuffer();
}
I would recommend to avoid using returned bitmap implicitly. The problem is that the memory for .NET objects is released by garbage collector not immediately when you leave the variable scope. This way if a lot of users run this code, it will be looking like a memory leak (which will be freed in some time, but you will have a peak of memory usage). That's why I would improve this code in the following way: Code:using( MemoryStream ms = new MemoryStream())
{
Aurigma.GraphicsMill.Bitmap bmp = Scene.Render(filenameBackground, filenameMask, arrParams, xmlFilename, _product);
bmp.Save(ms, new Aurigma.GraphicsMill.Codecs.BmpEncoderOptions());
bmp.Dispose();
return ms.GetBuffer();
}
Edited by user Monday, December 24, 2007 3:34:11 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Advanced Member
Groups: Guest
Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
> gmMask.LoadFromFile( filenameMask ); // must be 8bpp grayscale <---is this still true? If you are working with 8 bits per channel bitmaps (like 24-bit RGB, etc), the mask should be 8bppGrayscale. If you are working with extended pixels (16 bits per channel, like 48-bit RGB, etc), you should use 16bpp grayscale. I believe that you are always use 8-bit images. > gmFloor.Channels.Replace( gmMask, 3 ); <--- there is no more replace method As you noticed in the next post - you should use an indexer: Code:bmp.Channels[3] = mask; // = bmp.Channels.Replace(mask, 3) in GM 2.0
mask = bmp.Channels[3]; // = bmp.Channels.Extract(3) in GM 2.0
Edited by user Monday, December 24, 2007 3:34:23 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Advanced Member
Groups: Guest
Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
> convert an a gdi+ bitmap to and aurigma bitmap
Yes, now you can do it just using cast operator. Alternatively you can use ToGdiplusBitmap() method.
In the same way you may convert other types like graphics, font, pen, brush, color...
|
|
|
|
Rank: Advanced Member
Groups: Guest
Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
By the way, how do you display the result image to the user? Are you just saving the image into the Response?
I just thought that you could use the Web control. You could enable user to zoom, scroll, and pan the image, etc...
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
Thanks for the pointers Andrew. I will have a look at the web control, it may be a fit. It turns out that I was using that code for saving (or close to it): Code:// return the image as a byte array
using( MemoryStream ms = new MemoryStream())
{
using(Aurigma.GraphicsMill.Bitmap b = Scene.Render(filenameBackground, filenameMask, xmlParams, xmlFilename, _product))
b.Save(ms, new BmpEncoderOptions() );
return ms.GetBuffer();
}
Edited by user Monday, December 24, 2007 3:34:40 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
I'm having trouble getting a mask working. Under 2.0 I was using the following method (updated to v3, but doesnt give the desired result): Code:// create/add the mask for the floor
if( ! gmFloorResized.HasAlpha )
gmFloorResized.Channels.AddAlpha(0);
gmFloorResized.Channels[3] = gmMask;
gmFloorResized.Draw(gmBack, 0, 0, gmFloor.Width, gmFloor.Height, 0, 0, gmFloor.Width, gmFloor.Height, CombineMode.Alpha,0, InterpolationMode.HighSpeed);
Is there a new/better way of accomplishing this? I see in the help that there is a MaskedBitTransform.ApplyMaskTransform method, but I don't see how to use to accomplish what I want. Edited by user Monday, December 24, 2007 3:35:31 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
I'm trying to use the combiner class, but its not quite right. I seem to be able to get one image or the other, but not the alpha blended version. Here is my code: Code:using(Bitmap gmFloorResized = new Bitmap(gmMask.Width, gmMask.Height, PixelFormat.Format24bppRgb ))
{
using(Combiner c = new Combiner(gmFloor, new RectangleF(0,0,gmFloor.Width, gmFloor.Height), new RectangleF(float.Parse(xmlParams.GetAttribute("carpetOffsetX")), float.Parse(xmlParams.GetAttribute("carpetOffsetY")), gmFloor.Width, gmFloor.Height), CombineMode.Copy, 0, InterpolationMode.HighSpeed))
{
c.ApplyTransform(gmFloorResized);
}
RectangleF rf = new RectangleF(0, 0, gmFloorResized.Width, gmFloorResized.Height);
using(Combiner c = new Combiner(gmBack, rf, rf, CombineMode.Alpha, 1, InterpolationMode.HighSpeed))
{
c.ApplyMaskTransform(gmFloorResized, gmMask);
}
}
I'm trying to seem gmFloorResized into gmBack in accordance with gmMask. thanks! Edited by user Monday, December 24, 2007 3:35:48 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Member
Groups: Guest
Joined: 4/27/2004(UTC) Posts: 40
|
OK, after many tries I have come up with the following code that works: Code:RectangleF rf = new RectangleF(0, 0, gmFloorResized.Width, gmFloorResized.Height);
using(Combiner c = new Combiner( gmFloorResized, rf, rf, CombineMode.Alpha, 1, InterpolationMode.HighSpeed))
{
c.ApplyMaskTransform( gmBack, gmMask);
}
Some sample code in the documentation would have been a big help to me in this instance. Edited by user Monday, December 24, 2007 3:36:02 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Advanced Member
Groups: Guest
Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
We are considering adding code samples into the class reference. Meanwhile you could examine the section called "Programming with Graphics Mill". It contains a number of different code samples which will could be useful for you and give you more ideas how to use Graphics Mill features.
|
|
|
|
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.