I'm working on a program loading an image or capturing a screen area and convert them to simulate color blinds' vision.
The problem I've encountered now is that capturing algorithm doesn't work in different taskbar status that I wrote the code in.
The taskbar of my computer is set up to the top of the screen, and it's locked. I wrote the code in that status, and I realized that the program doesn't work on other computers with different taskbar status. I unlocked it or moved it to the other sides of the screen and it didn't work in the way as I wanted.
To capture a screen area, an opaque form is opened by the main one, and area to be captured is calculated from the position of mouse when its left button is pressed and released.
Also the position of mouse is shown by a label keeping following the cursor while it is hovering on the form. The label stops following the cursor while I'm pressing the left button.
I have no ides why it works like this.. Does any part of my code is affected by taskbar status? Appreciate in advance! The code is copied below.
public partial class Form_Capture_Rect : Form
{
//CaptureRectangular is the name of this form
private void CaptureRectangular_Load(object sender, EventArgs e)
{
int width = Screen.PrimaryScreen.Bounds.Width;
int height = Screen.PrimaryScreen.Bounds.Height;
this.FormBorderStyle = FormBorderStyle.None;
this.Size = new System.Drawing.Size(width, height);
Message_Capture.Left = (width - Message_Capture.Width) / 2;
Message_Capture.Location = new System.Drawing.Point((width - Message_Capture.Width) / 2, (height - Message_Capture.Height) / 2);
}
//src: position the left button of mouse is pressed
//dest: position it is released
//leftTop: gets smaller value from src and dest, X and Y respectively
//width, height: size of the captured image
int srcX, srcY;
int destX, destY;
int leftTopX, leftTopY;
int width, height;
//gets position of mouse when its left button is pressed
private void Form_Capture_MouseDown(object sender, MouseEventArgs e)
{
srcX = Cursor.Position.X;
srcY = Cursor.Position.Y;
//this.WindowState = FormWindowState.Minimized;
}
private void Form_Capture_MouseUp(object sender, MouseEventArgs e)
{
//the captured image will be shown onto a picturebox 'Pic_Unchanged' of the main form
Form_Main mainForm = Application.OpenForms["Form_Main"] as Form_Main;
PictureBox Pic_Unchanged = mainForm.Controls["Pic_Unchanged"] as PictureBox;
//gets the position of mouse when it's released
destX = Cursor.Position.X;
destY = Cursor.Position.Y;
//when its width or height is zero, the function is terminated
if (srcX == destX || srcY == destY)
{
mainForm.WindowState = FormWindowState.Normal;
this.WindowState = FormWindowState.Minimized;
this.Close();
}
else
{
//calculate out these for values to get image
leftTopX = srcX < destX ? srcX : destX;
leftTopY = srcY < destY ? srcY : destY;
width = srcX < destX ? destX - srcX : srcX - destX;
height = srcY < destY ? destY - srcY : srcY - destY;
Graphics myGraphics = this.CreateGraphics();
Bitmap memoryImage = new Bitmap(width, height, myGraphics);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
//copies image
mainForm.WindowState = FormWindowState.Normal;
this.WindowState = FormWindowState.Minimized;//whithout this, the form will be captured
memoryGraphics.CopyFromScreen(leftTopX, leftTopY, 0, 0, new Size(width, height));
//show the captured image onto the picturebox
Pic_Unchanged.Image = memoryImage;
this.Close();
}
}
//shows the position of mouse with a label following cursor
//MouseLoc is a label
private void Form_Capture_Rect_MouseMove(object sender, MouseEventArgs e)
{
MouseLoc.Location = new System.Drawing.Point(Cursor.Position.X, Cursor.Position.Y);
MouseLoc.Text = e.X + ", " + e.Y;
}
//Delete a text 'Message_Capture' which says "Capture Area" 2.5 seconds after the form is shown up
private void DeleteMessage_Tick(object sender, EventArgs e)
{
Message_Capture.Visible = false;
}
}
Related
So when ever I hold the left mouse button and draw the rectangle on the form.
The form itself keeps flickering.
I've tried setting the DoubleBuffered property to true, that didnt change anything.
Is there a way to change the refresh rate or something similar?
Because from what I've tried, the example above and
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
It doesnt seem to change anything
Here is a gif showing the flickering
https://i.imgur.com/Wa3kmbM.gifv
private void Form1_Load(object sender, EventArgs e)
{
//Hide the Form
this.Hide();
label1.Visible = false;
label2.Visible = false;
//Create the Bitmap (This is an a black bitmap holding just the size.) (Bitmap is mutable)
Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
//Create a graphics object that's ready for alteration. `printscreen` is now a graphics Object
Graphics graphics = Graphics.FromImage(printscreen);
//Alter the graphics object which again is the printscreen
graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size);
//Create a temporary memory stream for the image
using (MemoryStream s = new MemoryStream())
{
//save graphic variable into memory
printscreen.Save(s, ImageFormat.Bmp);
//Set the size of the picturebox
pictureBox1.Size = new Size(Width, Height);
//set the value of the picturebox.Image to an Image.FromStream and load the temp stream
pictureBox1.Image = Image.FromStream(s);
}
//Show Form
this.Show();
//Cross Cursor
Cursor = Cursors.Cross;
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//startX is holds the corresponding value of where the mouse is in relation to the pixels of the width
//for instance, if it's all the way to the right, it holds the value of 1920.
startX = e.X;
startY = e.Y;
selectPen = new Pen(Color.DimGray, 2);
selectPen.DashStyle = DashStyle.Dash;
pictureBox1.Refresh();
start = true;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (start)
{
pictureBox1.Refresh();
//selectingWidth is equal to how much we have selected from the starting point.
//Let's say the starting point is 10 and our current mouse position is at 10 then we have selected 0 pixels to the right.
//However if we move our mouse 10 pixels to the right it means we have selected 10 pixels to the right.
selectingWidth = e.X - startX;
selectingHeight = e.Y - startY;
//if the selectingWidth is less than 0, then set the origin to the current position of the mouse.
var drawfromX = selectingWidth < 0 ? e.X : startX;
var drawfromY = selectingHeight < 0 ? e.Y : startY;
pictureBox1.Refresh();
pictureBox1.CreateGraphics().DrawRectangle(selectPen,
drawfromX,
drawfromY,
Math.Abs(selectingWidth),
Math.Abs(selectingHeight));
}
}
So I am trying to recreate the Snipping Tool that comes with Windows.
However I've manage to get it to draw a rectangle from the top left corner and then when I move my cursor to the bottom right.
However if I try to move my cursor from let's say the middle of the screen to the top left it doesnt draw the rectangle.
Why is this?
Here is a GIF showing what happends
https://i.imgur.com/0Y7xXnS.gifv
//These variables control the mouse position
int selectX;
int selectY;
int selectWidth;
int selectHeight;
public Pen selectPen;
//This variable control when you start the right click
bool start;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//Hide the Form
this.Hide();
//Create the Bitmap (This is an a black bitmap holding just the size.) (Bitmap is mutable)
Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
//Create a graphics object that's ready for alteration. `printscreen` is now a graphics Object
Graphics graphics = Graphics.FromImage(printscreen);
//Alter the graphics object which again is the printscreen
graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size);
//Create a temporary memory stream for the image
using (MemoryStream s = new MemoryStream())
{
//save graphic variable into memory
printscreen.Save(s, ImageFormat.Bmp);
//Set the size of the picturebox
pictureBox1.Size = new Size(Width, Height);
//set the value of the picturebox.Image to an Image.FromStream and load the temp stream
pictureBox1.Image = Image.FromStream(s);
}
//Show Form
this.Show();
//Cross Cursor
Cursor = Cursors.Cross;
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
selectX = e.X;
selectY = e.Y;
selectPen = new Pen(Color.DimGray, 1);
selectPen.DashStyle = DashStyle.Solid;
pictureBox1.Refresh();
start = true;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (start)
{
selectWidth = e.X - selectX;
selectHeight = e.Y - selectY;
pictureBox1.Refresh();
pictureBox1.CreateGraphics().DrawRectangle(selectPen,
selectX, selectY, selectWidth, selectHeight);
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Stream sound = Resources.SnapshotSound;
SoundPlayer player = new SoundPlayer(sound);
player.PlaySync();
Application.Exit();
}
}
So what you end up with is basically a rectangle with a negative width and height.
You'll probably want to use the Math.Abs to make sure you get a proper width and height in the cases the difference would become negative.
With that, you will also probably want to draw from different positions based on where your cursor is in relation to the selected point. Something like
selectWidth = e.X - selectX;
selectHeight = e.Y - selectY;
// If width is less than 0, draw from pointer, otherwise from select X
var drawFromX = selectWidth < 0 ? e.X : selectX;
// If height is less than 0, draw from pointer, otherwise from select Y
var drawFromY = selectHeight < 0 ? e.Y : selectY;
pictureBox1.Refresh();
pictureBox1.CreateGraphics().DrawRectangle(selectPen,
drawFromX,
drawFromY,
Math.Abs(selectWidth), // Make sure the rectangle width is positive
Math.Abs(selectHeight)); // Make sure the rectangle height is positive
I want to grow a form when I click the button and it should be in the center of the screen .so I wrote following code snippet.
private void ord_Click(object sender, EventArgs e)
{
this.StartPosition = FormStartPosition.CenterScreen;
this.Size = new Size(1308,599);
this.Show();
}
But when I click the button window grows but half of the window can not see.Here is the picture of that.
GUI after growing
How can I get rid of this problem.?
Whats wrong with my code?
You have to compute both Size and Location:
private void ord_Click(object sender, EventArgs e) {
// Ensure that suggested form size doesn't exceed the screen width and height
this.Size = new System.Drawing.Size(
Screen.GetWorkingArea(this).Width >= 1308 ? 1308 : Screen.GetWorkingArea(this).Width,
Screen.GetWorkingArea(this).Height >= 599 ? 599 : Screen.GetWorkingArea(this).Height);
// locate the form in the center of the working area
this.Location = new System.Drawing.Point(
(Screen.GetWorkingArea(this).Width - Width) / 2,
(Screen.GetWorkingArea(this).Height - Height) / 2);
}
You can use the PrimaryScreen property of the Screen class.
//this.StartPosition = FormStartPosition.CenterScreen;
//this.Show();
Omit these lines you've written, except setting the Size property of the form:
private void ord_Click(object sender, EventArgs e)
{
this.Size = new Size(1308,599);
CenterForm();
}
Create a method named CenterForm() which will set a new location of the form. You can achieve this by calling this method in your button click event.
private void CenterForm()
{
int getWidth = Screen.PrimaryScreen.Bounds.Width;
int getHeight = Screen.PrimaryScreen.Bounds.Height;
int X = getWidth - this.Width;
int Y = getHeight - this.Height;
this.Location = new Point(X / 2, Y / 2);
}
Note: Always remember to anchor your controls when the size of the form has changed.
In For1 i have this code:
private void timer1_Tick(object sender, EventArgs e)
{
try
{
this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Load(file_array_satellite[file_indxs_satellite]);
file_indxs_satellite = file_indxs_satellite - 1;
if (file_indxs_satellite < 0)
{
file_indxs_satellite = file_array_satellite.Length - 1;
}
}
catch
{
timer1.Enabled = false;
}
}
private void satellitesToolStripMenuItem_Click(object sender, EventArgs e)
{
file_array_satellite = Directory.GetFiles(UrlsPath, "RainImage*.*");
if (file_array_satellite.Length > 0)
{
DateTime[] creationTimes8 = new DateTime[file_array_satellite.Length];
for (int i = 0; i < file_array_satellite.Length; i++)
creationTimes8[i] = new FileInfo(file_array_satellite[i]).CreationTime;
Array.Sort(creationTimes8, file_array_satellite);
file_indxs_satellite = 0;
file_indxs_satellite = file_array_satellite.Length - 1;
timer1.Enabled = true;
}
}
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
this.pictureBox1.Size = new Size(500, 500);
pictureBox1.Location = new Point(this.Bounds.Width / 2,
this.Bounds.Height / 2);
this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.BringToFront();
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
this.pictureBox1.Size = new Size(100, 100);
pictureBox1.Location = new Point(12,
27);
}
In the original the picturebox1 size is 100x100 and each image i stretch to fit in the pictureBox.
When it's 100x100 everything is ok i see the animation of each image in the pictureBox.
Now i did an event that when i enter with the mouse to the pictureBox area it should move to the center of the form resize to 500x500 stretch the images and show the same animation.
And when i leave the pictureBox area it should return to it's original size and location.
When i enter with the mouse to the pictureBox1 area the pictureBox just vanish i don't see it anywhere once i leave the pictureBox area i see it 100x100 in it's original place and size.
Why when i enter with the mouse to the pictureBox1 area it's vanish i don't see it in the center of the form on size 500x500 ?
file_array_satellite is string[] and file_indxs_satellite is int.
RainImage*.* are the files names on the hard disk after downloaded them.
The idea is not to convert/change the files sizes on the hard disk each time i enter or leave so i wanted that once i enter the pictureBox1 area it will stretch the current image in the pictureBox and show it . It's working when it's 100x100 but not on 500x500.
When you mouse over the PictureBox and move it to the center of the form, you are moving it out from under the mouse cursor. This causes the MouseLeave event to immediately trigger, which places it back under your mouse cursor again, which causes the MouseEnter event to trigger again, etc.
You can do something like this:
bool suppressMouseLeave;
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
suppressMouseLeave = true;
this.pictureBox1.Size = new Size(500, 500);
pictureBox1.Location = new Point(this.Bounds.Width / 2,
this.Bounds.Height / 2);
this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.BringToFront();
//point the cursor to the new Position so that it's still kept on the pictureBox1
//This is important because it makes your idea acceptable.
//Otherwise you have to move your mouse onto your pictureBox and leave the
//mouse from it then to restore the pictureBox
Cursor.Position = PointToScreen(new Point(pictureBox1.Left + 250, pictureBox1.Top + 250));
suppressMouseLeave = false;
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
if(suppressMouseLeave) return;
this.pictureBox1.Size = new Size(100, 100);
pictureBox1.Location = new Point(12, 27);
}
I would venture a guess that this.Bounds.Width and this.Bounds.Height are not what you expect them to be, so the PictureBox isn't vanishing, you are just setting it to some location that is offscreen/off your form. Run Visual Studio in Debug mode and put a breakpoint around that line and see what this.Bounds is equal to. This may give you a clue as to the proper location you need to set.
How about in "in place" zoom like this?
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
Rectangle rc = pictureBox1.Bounds;
rc.Inflate(200, 200);
pictureBox1.Bounds = rc;
pictureBox1.BringToFront();
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
Rectangle rc = pictureBox1.Bounds;
rc.Inflate(-200, -200);
pictureBox1.Bounds = rc;
}
I am creating an application, in which user will be able to Upload an image and then Zoom in and Out the image on a particular location (current mouse pointer).
Also user should be able to drag the image to see other parts of the image when the image is zoomed.
I have implemented some functionality to achieve it but i am scaling the complete image. I want to know that how i can scale a particular portion of image, or scale the complete image and then point to that location where my current mouse pointer is placed.
Code:
private void DisplayIsdDiagram(BO.IsdDiagram IsdDiagram)
{
DoubleBuffered = true;
zoomFac = 1;
translateX = 0;
translateY = 0;
transStartX = 0f;
transStartY = 0f;
picIsdDiagram.BorderStyle = BorderStyle.Fixed3D;
bmp = new Bitmap(Image.FromStream(new MemoryStream(IsdDiagram.Image.ToArray())));
if (bmp.Width > bmp.Height)
{
ratio = (float)picIsdDiagram.Width / (float)bmp.Width;
translateRatio = (float)bmp.Width / (float)picIsdDiagram.Width;
}
else
{
ratio = (float)picIsdDiagram.Height / (float)bmp.Height;
translateRatio = (float)bmp.Height / (float)picIsdDiagram.Height;
}
//picIsdDiagram.Image = bmp;
picIsdDiagram.Refresh();
picIsdDiagram.MouseWheel += new MouseEventHandler(picIsdDiagram_MouseWheel);
}
private void picIsdDiagram_MouseWheel(object sender, MouseEventArgs e)
{
IsZooming = true;
if (e.Delta < 0)
{
if (zoomFac > 1)
zoomFac = zoomFac - (float)0.1;
}
else
{
if (zoomFac <= 5)
zoomFac = zoomFac + (float)0.1;
}
picIsdDiagram.Refresh();
IsZooming = false;
}
private void picIsdDiagram_MouseDown(object sender, MouseEventArgs e)
{
IsZooming = false;
IsMouseDown = true;
transStartX = e.X;
transStartY = e.Y;
}
private void picIsdDiagram_MouseUp(object sender, MouseEventArgs e)
{
IsZooming = false;
IsMouseDown = false;
translateX = translateX + ((e.X - transStartX) * (translateRatio / zoomFac));
translateY = translateY + ((e.Y - transStartY) * (translateRatio / zoomFac));
picIsdDiagram.Refresh();
}
private void picIsdDiagram_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.ScaleTransform(ratio * zoomFac, ratio * zoomFac);
if (IsZooming == false && IsMouseDown == true)
g.TranslateTransform(translateX, translateY);
g.DrawImage(bmp, 0, 0);
}
I tried to get the current mouse position from MouseHover event and tried to Translate the picture when only Zoom is done, but that is not working.
Also the Picture Box has some other multiple Picture boxes inside it, to show some representation on the big image. While scaling the Big Image, small images (inside images) should not be scaled. Although there position needs to be recalculated to show them at their real places even after zooming on the Big image.
So in above i am facing two problems:
1) To Zoom an Image at any particular location (current mouse pointer)
by scrolling.
2) To regenerate the coordinates of the sub images while
zooming and translating.
Any help that can guide me in correct direction.
Also if by any other means, i could be able to achieve this functionality.
Application : Windows
Control : Picture Box (Please suggest if any other control can be used, if not possible with this)
Language : C#
Waiting for response!
PictureEdit control provided by DevExpress 13.2