This forum contains outdated content and is available for reading only. Please contact technical support if you have any questions.

Notification

Icon
Error

Options
Go to last post Go to first unread
tcrosbie  
#1 Posted : Thursday, July 3, 2008 5:41:43 PM(UTC)
tcrosbie

Rank: Advanced Member

Groups: Guest
Joined: 6/22/2008(UTC)
Posts: 27

I'm probably missing something really simple here.

I'm using a multiLayerViewer, and adding ImageVObjects to it. What I want to do is apply Tranforms and Effects to the currently selected ImageVObject. I'm having difficulty finding how to do this. Transforms all seem to take bitmaps as an argument in the ApplyTransform methods, and obviously ImageVObjects don't have access to bitmaps directly through any methods or properties.

Could someone point me in the right direction to getting transforms, (Contrast, Redeye, Emboss etc), working on an ImageVObject.

Thanks.
Alex Kon  
#2 Posted : Sunday, July 6, 2008 1:22:08 PM(UTC)
Alex Kon

Rank: Advanced Member

Groups: Guest
Joined: 1/31/2005(UTC)
Posts: 458

Was thanked: 5 time(s) in 5 post(s)
Hello,

No, its not you. Actually it is feature which is not accessible in current version. If you want to change ImageVObject, you should apply necessary transform to the original image and recreate it.

Another way is to create an subclass and implement such features inside it.
tcrosbie  
#3 Posted : Sunday, July 6, 2008 4:25:44 PM(UTC)
tcrosbie

Rank: Advanced Member

Groups: Guest
Joined: 6/22/2008(UTC)
Posts: 27

Hi alex,

Thanks for the reply, I did email support as well. Andrew suggested 3 methods.

Using the Draw method of the object to draw to a bitmap, transform, replace the orginal object with the transformed bitmap, (which I was part way through implementing).
Using reflection to access the data (get access to the _image variable of the ImageVObject), transform then replace the original object with the transformed bitmap.
Subclassing.

I decided on method 2 and am using reflection to get the data, apply the transform to the bitmap and then replace the object, which seems to be working well, and more effectively than the draw method, (for me anyway).

Tyler

Edited by user Sunday, July 6, 2008 4:26:45 PM(UTC)  | Reason: Not specified

Alex Kon  
#4 Posted : Tuesday, July 8, 2008 1:31:42 PM(UTC)
Alex Kon

Rank: Advanced Member

Groups: Guest
Joined: 1/31/2005(UTC)
Posts: 458

Was thanked: 5 time(s) in 5 post(s)
Hi Tyler,

Yes, it is good idea. Reflection is a sort of "unfair" tool, but in your case it is a quite reasonable choise ;).
ChingYen  
#5 Posted : Wednesday, July 9, 2008 1:04:46 PM(UTC)
ChingYen

Rank: Advanced Member

Groups: Guest
Joined: 3/3/2008(UTC)
Posts: 185

Thanks: 8 times
May I know why draw is expansive. I plan to do something like that....please advice...
tcrosbie  
#6 Posted : Wednesday, July 23, 2008 6:02:35 PM(UTC)
tcrosbie

Rank: Advanced Member

Groups: Guest
Joined: 6/22/2008(UTC)
Posts: 27

Sorry for the delay, I've had my head in code.

Ok, draw for me wasn't the best option because I personally found the reflection method, was quicker to implement, and gave me more flexibility, (I did end up subclassing as well, for something else... I think the draw method would have impacted on this). As it stands now, I have all the functionality of a BitmapViewer, available on vObjects. I did try writing back to the vObject bitmap... But that caused all sorts of memory locking problems. So I'm staying with replacing the existing object.

My next challenge is serialised data. My app is generating enormous files, I need to find a way to reduce file size, and not impact on performance, or quality. Yeah I know I don't ask for much right? :)
tcrosbie  
#7 Posted : Thursday, July 24, 2008 12:24:36 PM(UTC)
tcrosbie

Rank: Advanced Member

Groups: Guest
Joined: 6/22/2008(UTC)
Posts: 27

I'm being a little bit bloggy here, hopefully this info will help someone else.

Turns out that subclassing and reflection were both good choices, I was able to implement an optimizing routine in the ImageVObject subclass that examines the image, determines what size it's going to print at, and then resize the image down if needed to a given dpi value, (eg 300dpi).

I was using scaling to manipulate the file size, of course if you add three 4 meg jpgs to the MLV, (3504x2678 pixels), then serialise that layer, you wind up with a seriously big file, (I'm talking over 70 meg here).

So right before serialisation, go through all the images, work out if their image size, (gained through reflecting the _image private variable in the ImageVObject), is bigger than needed, and if it is, resize the image to the required size.

I managed to reduce file size from 70 meg, down to 13 by doing this alone, which makes things much more manageable.
Alex Kon  
#8 Posted : Thursday, July 24, 2008 4:55:51 PM(UTC)
Alex Kon

Rank: Advanced Member

Groups: Guest
Joined: 1/31/2005(UTC)
Posts: 458

Was thanked: 5 time(s) in 5 post(s)
Hi tcrosbie,

Thank you for your posts here, I think they can be really helpful.

As for locking issues - we both know that using reflection here is actually a small hack. It's not a bad, I think that each of us uses them from time to time ;).

And in the solution you described above (resize before serialization) reflection gives simple and efficient solution - I think I like it. The only thing I want to warn you - do not use serialization for long-term storage. Internal serialization format is a subject to change in future versions of the Graphics Mill for .NET.
tcrosbie  
#9 Posted : Friday, July 25, 2008 12:58:38 PM(UTC)
tcrosbie

Rank: Advanced Member

Groups: Guest
Joined: 6/22/2008(UTC)
Posts: 27

Hi Alex,

Thanks, I am aware of the dangers of using serialisation as a long term solution, it suits my needs right now, (quick, effective), but I will be looking to use another method for permanent storage.

For caching purposes serialisation is working very well, and removes a lot of memory hassles for me.

Tyler
plawi48  
#10 Posted : Thursday, November 27, 2008 1:13:26 AM(UTC)
plawi48

Rank: Newbie

Groups: Guest
Joined: 11/27/2008(UTC)
Posts: 1

Hello,
I'm trying to do the same as you but it doesn't seem to work.
I subclassed ImageVObject and added one method to update the image (after applying some effects for instance...)

Code:


 public void setBitmap(Bitmap b)
{
            FieldInfo pFieldInfo  = typeof(ImageVObject).GetField("_image", BindingFlags.Instance | 
     BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public);

            pFieldInfo.SetValue(this,b);
            
            this.Update();
}




Could you please give a piece of code doing it ?

Thank you.

Loïc
Alex Kon  
#11 Posted : Sunday, November 30, 2008 9:06:51 PM(UTC)
Alex Kon

Rank: Advanced Member

Groups: Guest
Joined: 1/31/2005(UTC)
Posts: 458

Was thanked: 5 time(s) in 5 post(s)
Hello,

The point is that ImageVObject uses another variable internally to cache image - _drawnImage. Try to null it. In my test it helps. The code is almost the same:

Code:
public class ImageVObjectEx : Aurigma.GraphicsMill.WinControls.ImageVObject
{
    public ImageVObjectEx(Aurigma.GraphicsMill.Bitmap img, bool scaleToActualSize, float x, float y)
        : base(img, scaleToActualSize, x, y)
    {
    }

    public void SetImage(Aurigma.GraphicsMill.Bitmap value)
    {
        FieldInfo fi = typeof(ImageVObject).GetField(
            "_image", 
            BindingFlags.Instance | 
                BindingFlags.FlattenHierarchy | 
                BindingFlags.NonPublic | 
                BindingFlags.Public);
        
        fi.SetValue(this, value);

        fi = typeof(ImageVObject).GetField(
            "_drawnImage", 
            BindingFlags.Instance | 
                BindingFlags.FlattenHierarchy | 
                BindingFlags.NonPublic | 
                BindingFlags.Public);
        
        fi.SetValue(this, null);

        this.Update();
    }
}
Loïc  
#12 Posted : Monday, December 1, 2008 3:30:06 AM(UTC)
Loïc

Rank: Newbie

Groups: Guest
Joined: 11/27/2008(UTC)
Posts: 2

Thank you Alex,

I've tried your code. The image on the MultiLayerViewer is not updated until I resize it with the mouse. Any idea how to force the image to be redrawn ?

Thank you.

Loïc

HabaHaba  
#13 Posted : Tuesday, December 2, 2008 3:13:57 PM(UTC)
HabaHaba

Rank: Member

Groups: Guest
Joined: 9/7/2008(UTC)
Posts: 19

Hi,
I have implemented similar task: apply set of filters (like Brightness/Contrast, Hue/Saturation and more) to the ImageVObject and each filter can be enabled/disabled or removed. To do this in ImageVObject subclass I replace old image with new in this code:
Code:
/// <summary>
		/// Заменяет текущее отображение новым. Контроля размеров не производится
		/// </summary>
		public void ReplaceImage(Bitmap newImage)
		{
			if (newImage == null)
				throw new ArgumentNullException("newImage");

			var flags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic;
			// clear cashed image
			typeof(ImageVObject).GetField(
				"_drawnImage",
				flags
			).SetValue(this, null);
			// ...and parameter used for check if cashe image valid 
			typeof(ImageVObject).GetField(
				"_cachedZoom",
				flags
			).SetValue(this, -1.0f);

			// set new image
			typeof(ImageVObject).GetField(
				"_image",
				flags
			).SetValue(this, newImage);
			
			Update();
		}


--
Sergey
Loïc  
#14 Posted : Tuesday, December 2, 2008 7:57:19 PM(UTC)
Loïc

Rank: Newbie

Groups: Guest
Joined: 11/27/2008(UTC)
Posts: 2

Thank you a lot HabaHaba, your solution is working fine for me.

Loïc
mzhao  
#15 Posted : Friday, September 17, 2010 1:11:28 AM(UTC)
mzhao

Rank: Advanced Member

Groups: Guest
Joined: 9/10/2010(UTC)
Posts: 57

Thanks: 1 times
This is great . This seems to be what we are looking for for image animation. Thanks everyone here.

But Alex, this solves one issue here. But we may have something more complicate for you to help us out:

Besides those animated images, we want to dynamically redraw some complex shapes according to a particular value just as redraw different images here.

It seems that we have to do this on the base of VObject because no single existing one can do what we want to do. No LineVObject nor RectangleVObject nor EllipseVObject, etc.

Here are some examples :

A Rectangle Text Box : something which combine TextVOBject and RectangleVOBject as a single object. It has all the features of other Derived VObject such resize, rotate, etc.

A Gauge Meter , which may be more involved than the above one. It needs PolyLine, Text, Rectangle , Line, etc to combine as one and dynamically redraw changes.

So it seems that we have to implement override draw method of VObject and use the derived object in the same way as other derived objects such as ImageVObject in regard to editing on the multilayerviewer.
Alex Kon  
#16 Posted : Sunday, September 19, 2010 2:49:32 PM(UTC)
Alex Kon

Rank: Advanced Member

Groups: Guest
Joined: 1/31/2005(UTC)
Posts: 458

Was thanked: 5 time(s) in 5 post(s)
Hello mzhao,

I can suggest you 2 ways. If you composite object is simple - it may be possible just to unite several VObjects into one using CompositeVObject class. They will be treated as single object and will be resized/moved together. However it will work only with very simple objects.

Otherwise, it will be better to do this in your way - create new object based on VObject. In that case I recommend you to take a look into VectorObjects source code. Internals of existing vector objects may be very helpful for you.
Users browsing this topic
Guest (7)
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.