NextPVR Forums
  • ______
  • Home
  • New Posts
  • Wiki
  • Members
  • Help
  • Search
  • Register
  • Login
  • Home
  • Wiki
  • Members
  • Help
  • Search
NextPVR Forums Public Developers v
« Previous 1 … 70 71 72 73 74 … 93 Next »
who is good at maths?

 
  • 0 Vote(s) - 0 Average
who is good at maths?
smeghead
Offline

Senior Member

Posts: 300
Threads: 23
Joined: Jan 2005
#11
2005-07-06, 09:09 PM
You need to maintain the centre of the image as your referenced coordinates.

SUBROUINE
void MyDrawImage(int CentreX, int CentreY, int Width, int Height )
{
int W = Width / 2;
int H = Height / 2;

// Set SourceImage to be the rectangle coordinates in the image file
System.Drawing.Rectangle SourceImage = new System.Drawing.Rectangle(CentreX - W, CentreY - H , Width, Height)

// Set DestImage to be the rectangle coordinates on the screen where the image is to be placed
System.Drawing.Rectangle DestImage = new System.Drawing.Rectangle(60,60,500,500) // put your numbers here

Graphics.FromImage(backgroundImage).DrawImage(TheJPEGAsAnImage, DestImage , SourceImage , GraphicsUnit.Pixel,imageAttr);
}


MAIN ROUTINE

// Initialisation
// I Assume That TheImageWidth and TheImageHeight are declared to be the source jpeg image width and height respectivelly


int CentreX, CentreY, Width, Height;
double Zoom = 1.0;
CentreX = TheImageWidth / 2;
CentreY = TheImageHeight / 2;

// Zoom in
Zoom = Zoom * 2.0;
if ( Zoom >= 64.0 ) then Zoom = 64.0; // just to bound the value
Width = TheImageWidth / Zoom;
Height = TheImageHeight / Zoom;
MyDrawImage ( CentreX, CentreY, Width, Height);

// Zoom out
Zoom = Zoom / 2.0;
if ( Zoom < 1.0 ) then Zoom = 1.0; // just to bound the value
Width = TheImageWidth / Zoom;
Height = TheImageHeight / Zoom;
MyDrawImage ( CentreX, CentreY, Width, Height);

// Pan left
CentreX = CentreX - 10 // 10 is my pan value, use yours
Width = TheImageWidth / Zoom;
Height = TheImageHeight / Zoom;
MyDrawImage ( CentreX, CentreY, Width, Height);

// Pan Right
CentreX = CentreX + 10 // 10 is my pan value, use yours
Width = TheImageWidth / Zoom;
Height = TheImageHeight / Zoom;
MyDrawImage ( CentreX, CentreY, Width, Height);

// Pan Up
CentreY = CentreY - 10 // 10 is my pan value, use yours
Width = TheImageWidth / Zoom;
Height = TheImageHeight / Zoom;
MyDrawImage ( CentreX, CentreY, Width, Height);

// Pan Down
CentreY = CentreY + 10 // 10 is my pan value, use yours
Width = TheImageWidth / Zoom;
Height = TheImageHeight / Zoom;
MyDrawImage ( CentreX, CentreY, Width, Height);




The only thing I haven't included is if the image is zoomed in, panned across one direction and then the user zooms out you will have to update CentreX and/or CentreY to reposition the image location.
reven
Offline

Posting Freak

Posts: 5,782
Threads: 396
Joined: Sep 2004
#12
2005-07-06, 09:30 PM
looks like you've done this before Smile

the width and height i use are the best fit to the window, not the image size, so zoom=1 doesnt actually equal the actual image size, just the width/height to get the image to fill the screen the best, but thats not really important.

and for this part, since you seem to know what you are doing
Code:
System.Drawing.Rectangle DestImage = new System.Drawing.Rectangle(60,60,500,500) // put your numbers here

Graphics.FromImage(backgroundImage).DrawImage(TheJ PEGAsAnImage, DestImage , SourceImage , GraphicsUnit.Pixel,imageAttr);
is there anyway to reduce an image quality? like theres not much point drawing a 3megapixel image to 720x480, it just takes longer and no benefit (i only just discovered the imageattribute and dest/source in the last few days, when playing around with fading in/out (before i was just drawing the image the full image offscreen, not very efficient).

i wont get a chance to play around with this until tomorrow, going to see ff4 now, hopefullyy it will be good Smile
Heyt
Offline

Member

Posts: 106
Threads: 9
Joined: Jan 2005
#13
2005-07-06, 10:10 PM
OK did not think of the centering problem.
But now i think i have a solution for your problem. If you zoom and the picture is greater than the screen, then with your code the picture will not show the same part of the picture then before zooming and this is because you can zoom everything about the image but not the screen. So you need to know how much of the picture is on the left, top off the screen (before zoom) and then recalulate the position of the visible screen. And you have to know the position of the coordinate (0,0), because as far as i understood it is not the top/left most corner of the screen, but the top/left corner of the not zoomed image.
So at least for zoom this code should work (i hope my C is not too bad)

Quote:double leftpos = //will be the difference between 0,0 coordinate and the left most position on the screen (positive value)
double toppos = //will be the difference between 0,0 coordinate and the top most position on the screen (positive value)

double leftoff = (-1 * current.X) - leftpos;
double topoff = (-1 * current.Y) - toppos;

double oldWidth = current.Width;
double oldHeight = current.Height;

current.Width = current.OriginalWidth * current.Zoom;
current.Height = current.OriginalHeight * current.Zoom;

if (oldWidth <= ScreenWidth)
{
current.X -= ((current.Width - oldWidth) / 2);
}
else
{
current.X = (-1 * leftoff * current.Zoom / oldZoom) - (((ScreenWidth * current.Zoom / oldZoom) - ScreenWidth) / 2) - leftpos;
}

if (oldHeight <= ScreenHeight)
{
current.Y -= ((current.Height - oldHeight) / 2);
}
else
{
current.Y = (-1 * topoff * current.Zoom / oldZoom) - (((ScreenHeight * current.Zoom / oldZoom) - ScreenHeight) / 2) - toppos;
}

I just saw the other post with a solution, so maybe i'm a bit late, but after i thought about it an hour i like to post it, maybe you can find something usefull in it
smeghead
Offline

Senior Member

Posts: 300
Threads: 23
Joined: Jan 2005
#14
2005-07-06, 10:30 PM (This post was last modified: 2005-07-06, 10:55 PM by smeghead.)
I dont understand when you say that the width and height are the best fit to the window. The screen window is fixed in size. My Width and Height variables reference the source jpeg image. This jpeg image rectangle I define in the subroutine is "stretched" or "shrunk" by DrawImage to fit the screens width and height you give it as DestImage.

These are all the overloaded DrawImage methods

http://msdn.microsoft.com/library/defaul...etopic.asp

All I have done in the subroutine is tell it to take a source rectangle from the image (that must always be equal to or part of the image) and "stretch" or "shrink" it by whatever means to the destination rectangle on the screen. The method itself does the image quality conversion. The widths and heights dont have to be the same but its best if they are "multiples of 2" or you get aliasing and worse degredation. In the code you notice I keep doing multiples of 2 (i.e. 1,2,4,8,16) for Zoom.

One possible way of reducing a large image size is to use exactly the same function DrawImage but just once. I mean, draw from one image to another using DrawImage. The source rectangle is the large image size (from the 3MPixel image in your example) and draw that into an image the size of 720*480 or whatever size suits you. Just make sure you declare the Image variable large enough to hold the size you give it. In this case DrawImage will "shrink" the image for you in the best way it can.

Look at the C# example on this page. Instead of painting the image on screen, you paint it into another Image - just like the way sub does it for his interface we use.
http://msdn.microsoft.com/library/defaul...opic11.asp

What we actually do is: sub gives us the opportunity to produce an image that we pass to him and he paints it on the screen. The plugins do not directly paint onto the screen.

Read the text above the example:
"The position of the destination rectangle locates the image on the screen, the sizes of the source and destination rectangles determine the scaling of the drawn image, and the size of the source rectangle determines what portion of the original image is drawn to the screen."

In other words, DrawImage does all the scaling for you given a source rectangle inside the image and a destination rectangle. These Do Not Have To Match In Size.

By the way, the DrawImage I used in the example doesnt exist. Either take off the imageAttr parameter or break down the second rectangle and make individual floats. You'll see what I mean, don't produce the SourceImage variable, just use the params.

You could also put Width amd Height in the subroutine and pass in Zoom but I did it the way I did to illustrate to you.


So, in my example when you zoom in: You essentially take a smaller width and height from the source image (given CentreX and CentreY position) and blit it to the same size screen image you always use. This creates a zoom in effect.

In my post when I said:
The only thing I haven't included is if the image is zoomed in, panned across one direction and then the user zooms out you will have to update CentreX and/or CentreY to reposition the image location.

What I mean is:
You need to put "if" tests in the main routine to make sure that you do not exceed the boundary of the original source image.
// if the right edge of the source rectangle is outside the source image right edge then bring it back.
if ( CentreX + (Width/2) > SourceImageWidth ) then
CentreX = SourceImageWidth - (Width/2);
// if the left edge of the source rectangle is outside the source image left edge then bring it back.
if ( CentreX - (Width/2) < 0 ) then
CentreX = SourceImageWidth + (Width/2);
// if the bottom edge of the source rectangle is outside the source image bottom edge then bring it back.
if ( CentreY + (Height/2) > SourceImageHeight ) then
CentreY = SourceImageHeight - (Height/2);
// if the top edge of the source rectangle is outside the source image top edge then bring it back.
if ( CentreY - (Height/2) < 0 ) then
CentreY = SourceImageHeight + (Height/2);

You need all 4 of these test before each call to MyDrawImage
(or you may be able to put it inside MyDrawImage just the once if you have global variables for CentreY and CentreX)

Hope this all helps.............
reven
Offline

Posting Freak

Posts: 5,782
Threads: 396
Joined: Sep 2004
#15
2005-07-07, 01:08 AM
Quote:I dont understand when you say that the width and height are the best fit to the window. The screen window is fixed in size. My Width and Height variables reference the source jpeg image. This jpeg image rectangle I define in the subroutine is "stretched" or "shrunk" by DrawImage to fit the screens width and height you give it as DestImage.
i stretch the width to fit the entire screen then i scale the height to the same scale, if the height is then larger than the screen image, i set the height to the screen height and i scale the width by the same scale. so the image eg 360x100 is scaled up to 720x200 to fill the screen. that is then considered to be zoom = 1.

Quote:Hope this all helps.............
yeah it all helps Smile just probably need a little bug fixing when i implemented tomorrow.

currently the image transistions on a few images can be a little jerky for large images, im just fiddling around trying to fix this. im not sure if double buffering will work for this, since ive only ever implemented that once and that was at stage 1 computer science (where they just said "put this code here, dont worry how it works, it just does", and that was it...).
reven
Offline

Posting Freak

Posts: 5,782
Threads: 396
Joined: Sep 2004
#16
2005-07-07, 12:16 PM (This post was last modified: 2005-07-07, 12:22 PM by reven.)
ok tried implementing this. for Heyts code, im not sure what these values should be
Code:
double leftpos = //will be the difference between 0,0 coordinate and the left most position on the screen (positive value)
double toppos = //will be the difference between 0,0 coordinate and the top most position on the screen (positive value)
since they seem they would be the same as these values
Code:
double leftoff = (-1 * current.X) - leftpos;
double topoff = (-1 * current.Y) - toppos;
without the subtraction, but once that is done for leftoff/topoff those values would be then 0, always.

and for smegheads code, the zoom in doesnt seem to take into consideration for the x position, or is this not important ?
Code:
// Zoom in
Zoom = Zoom * 2.0;
if ( Zoom >= 64.0 ) then Zoom = 64.0; // just to bound the value
Width = TheImageWidth / Zoom;
Height = TheImageHeight / Zoom;
MyDrawImage ( CentreX, CentreY, Width, Height);

// Zoom out
Zoom = Zoom / 2.0;
if ( Zoom < 1.0 ) then Zoom = 1.0; // just to bound the value
Width = TheImageWidth / Zoom;
Height = TheImageHeight / Zoom;
MyDrawImage ( CentreX, CentreY, Width, Height);
and the zoom factors are quite large, i set the max to 10, not 64 Smile
reven
Offline

Posting Freak

Posts: 5,782
Threads: 396
Joined: Sep 2004
#17
2005-07-07, 12:52 PM
heres the class that handles everything to do with the image size,position. if you need to use the screen size, just use indicate via "Bounds".
Code:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace MyPicturesPlugin.Controls
{
    public class ImageHelper
    {
        private double zoom = 1;
        private double x,y,width,height, centreX, centreY;
        private double origX, origY, origWidth, origHeight;
        private int imageWidth, imageHeight;
        internal ColorMatrix colorMatrix = new ColorMatrix();
        internal ImageAttributes imageAttributes = new ImageAttributes();

        public ImageHelper(double x, double y, double width, double height, int imageWidth, int imageHeight)
        {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.origX = x;
            this.origY = y;
            this.origWidth = width;
            this.origHeight = height;
            this.zoom = 1;
            this.imageWidth = imageWidth;
            this.imageHeight = imageHeight;
            this.centreX = width/2;
            this.centreY = height/2;
        }


        public void ZoomIn()
        {
            if(zoom<1)
            {                    
                zoom+=0.1;
            }
            else if(zoom < 4)
            {
                zoom+=0.5;
            }
            else if(zoom < 10)
            {                
                zoom++;
            }            
            width = origWidth * zoom;
            height = origHeight * zoom;
        }

        public void ZoomOut()
        {
            if(zoom > 4)
            {
                zoom--;
            }
            else if(zoom>1)
            {
                zoom-=0.5;
            }
            else if(zoom >0.4)
            {
                zoom-=0.1;
            }        
            width = origWidth * zoom;
            height = origHeight * zoom;
        }


        public void MoveLeft()
        {    
            centreX = centreX - 10;        
        }
        public void MoveRight()
        {
            centreX = centreX + 10;        
        }
        public void MoveDown()
        {
            centreY = centreY + 10;
        }
        public void MoveUp()
        {
            centreY = centreY - 10;
        }

        public double CentreX
        {
            get
            {
                return centreX;
            }
        }

        public double CentreY
        {
            get
            {
                return centreY;
            }
        }

        public double X
        {
            get
            {
                return this.x;
            }
            set
            {
                this.x = value;
            }
        }

        public double Y
        {
            get
            {
                return this.y;
            }
            set
            {
                this.y = value;
            }
        }

        public double Width
        {
            get
            {
                return this.width;
            }
            set
            {
                this.width = value;
            }
        }

        public double Height
        {
            get
            {
                return this.height;
            }
            set
            {
                this.height = value;
            }
        }

        public double Zoom
        {
            get
            {
                return this.zoom;
            }
            set
            {
                this.zoom = value;
            }
        }

        public double OriginalX
        {
            get
            {
                return this.origX;
            }
            set
            {
                this.origX = value;
            }
        }

        public double OriginalY
        {
            get
            {
                return this.origY;
            }
            set
            {
                this.origY = value;
            }
        }

        public double OriginalWidth
        {
            get
            {
                return this.origWidth;
            }
            set
            {
                this.origWidth = value;
            }
        }

        public double OriginalHeight
        {
            get
            {
                return this.origHeight;
            }
            set
            {
                this.origHeight = value;
            }
        }

        public Rectangle ImageBounds
        {
            get
            {
                return new Rectangle((int)this.x,(int)this.y,(int)this.width,(int)this.height);
            }
        }

        public int ImageWidth
        {
            get
            {
                return this.imageWidth;
            }
        }

        public int ImageHeight
        {
            get
            {
                return this.imageHeight;
            }
        }
    }

}
smeghead
Offline

Senior Member

Posts: 300
Threads: 23
Joined: Jan 2005
#18
2005-07-07, 01:02 PM
OK I think I see what you mean:

Double Buffering: This was a technique I used years ago. Essentially you have 2 frame buffers (images to draw on). While one buffer is being displayed on the screen the other is being used to draw onto. When the drawing is finished on the hidden frame buffer, the buffers are switched. The hidden one becomes the show one and vice versa. The now hidden buffer is wiped and draw on again.
In this way the actual drawing is not shown to the user. The user doesn't see ractangles being draw one after another, all they see is the finished product. All the user sees on screen are complete frames. This is a technique still used today on graphics cards for 3D games.
sub sort of implements this already (any comments sub?). sub displays a screen and asks the plugin to draw the next screen. When that is returned to sub he essentially gives the windows system that image as the next image to display and then asks the plugin for the next image.

As far as my code, the x position is done as part of the subroutine. What you need to do to maintain aspect ratio is to work out the area of the screen to draw in and maintain the same ratio as the original image. You can do this in the subroutine as well. So instead of the (60,60,500,500) in my original subroutine you need to calculate an area of the screen to draw in that maintains the aspect ratio.

Let me know how you get on. I'll have a bit more of a think and get back to it later
reven
Offline

Posting Freak

Posts: 5,782
Threads: 396
Joined: Sep 2004
#19
2005-07-07, 01:27 PM
im not sure what you mean by
Quote:So instead of the (60,60,500,500) in my original subroutine you need to calculate an area of the screen to draw in that maintains the aspect ratio.

heres the current method im using for the drawing
Code:
private void MyDrawImage(ref Image compositeScreenImage, ref Image image, ImageHelper helper)
        {
            double W = (helper.Width / 2);
            double H = (helper.Height / 2);

            // Set SourceImage to be the rectangle coordinates in the image file
            System.Drawing.Rectangle SourceImage = new System.Drawing.Rectangle((int)(helper.CentreX - W), (int)(helper.CentreY - H), (int)helper.Width, (int)helper.Height);

            // Set DestImage to be the rectangle coordinates on the screen where the image is to be placed
            //System.Drawing.Rectangle DestImage = new System.Drawing.Rectangle(60,60,500,500); // put your numbers here
            System.Drawing.Rectangle DestImage = Bounds;

            Graphics.FromImage(compositeScreenImage).DrawImage(image,DestImage,SourceImage.X,SourceImage.Y,SourceImage.Width,SourceImage.Height,GraphicsUnit.Pixel,helper.imageAttributes);                        
        }
which looks wrong to me, since the drawimage params are
drawImage(image, imagebounds, srcx, srcy,srcwidth,srcheight,graphicunit, imageattribute)
imagebounds = the bounds on the screen to draw eg fullscreen would be 720x480
srcx = the xposition in the original coordinate system for the image (ie currentx/zoom factor)
srcy = same as srcx just with y
srcwidth = the width of the image to draw in the original coordinate system, ie widht/zoom
srcheight = same srcwidth just with height.



this is what im using to draw the image as it fades in (at zoom = 1)
Code:
Graphics.FromImage(compositeScreenImage).DrawImage(currentImage,current.ImageBounds,0,0,currentImage.Width,currentImage.Height,GraphicsUnit.Pixel,current.imageAttributes);
0,0,curretImage.Width, currentImage.Height = draw the entire image, eg for an image of 120x120 thats what the width and height will be.
reven
Offline

Posting Freak

Posts: 5,782
Threads: 396
Joined: Sep 2004
#20
2005-07-07, 04:30 PM
ok i know what i need now, the best way is to move along via the centre, it makes sense. the imagebounds will always been constant, the screen size, ie 720x480. so all i need is a method to get the source rectangle. ie what part of the original image i want to draw (in the original image dimensions, ie a 360x240, the width of that is 360). so when zoomed at level 1, the and the image is centred, the rectangle i want is 0,0,360,240, ie i want to draw the entire rectangle since it fills the screen the best. but for a rectangle 360x230 i want the rectangle, 0,-10,360,260 (i think, pretty sure). and for 360,240 at zoom level 2, centred i want 90,60,270,180 (i think).

im sick of this now, two many diagrams all over my desk, just want to get this working....
« Next Oldest | Next Newest »

Users browsing this thread: 1 Guest(s)

Pages (4): « Previous 1 2 3 4 Next »


Possibly Related Threads…
Thread Author Replies Views Last Post
  What's a good Open Source VB.net plugin that I could browse? zehd 0 1,175 2007-01-30, 02:00 AM
Last Post: zehd
  Anyone recommend a good C# book? bgowland 9 3,581 2005-01-03, 07:32 PM
Last Post: bgowland

  • View a Printable Version
  • Subscribe to this thread
Forum Jump:

© Designed by D&D, modified by NextPVR - Powered by MyBB

Linear Mode
Threaded Mode