I am trying to make a trackbar which will zoom in and out on a picture in a picturebox. This is my current code:
namespace Zoom_in_and_Out_Tool
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Image imgOriginal;
private void Form1_Load(object sender, EventArgs e)
{
// set image location
imgOriginal = Image.FromFile(#"C:\New Folder\picture1.jpg");
picBox.Image = imgOriginal;
// set Picture Box Attributes
picBox.BackgroundImageLayout = ImageLayout.Stretch;
// set Slider Attributes
zoomSlider.Minimum = 1;
zoomSlider.Maximum = 5;
zoomSlider.SmallChange = 1;
zoomSlider.LargeChange = 1;
zoomSlider.UseWaitCursor = false;
// reduce flickering
this.DoubleBuffered = true;
}
public Image PictureBoxZoom(Image img, Size size)
{
Bitmap bm = new Bitmap(img, Convert.ToInt32(img.Width * size.Width), Convert.ToInt32(img.Height * size.Height));
Graphics grap = Graphics.FromImage(bm);
grap.InterpolationMode = InterpolationMode.HighQualityBicubic;
return bm;
}
private void zoomSlider_Scroll(object sender, EventArgs e)
{
if (zoomSlider.Value > 0)
{
picBox.Image = null;
picBox.Image = PictureBoxZoom(imgOriginal, new Size(zoomSlider.Value, zoomSlider.Value));
}
}
}
}
Currently it comes up with 2 problems. One being it does want to compile with the line grap.InterpolationMode = InterpolationMode.HighQualityBicubic; . The Second problem is that when i try to zoom it comes up with the error: " "ArgumentException was unhandled" error at the line: Bitmap bm = new Bitmap(img, Convert.ToInt32(img.Width * size.Width), Convert.ToInt32(img.Height * size.Height)); " Any help would be great,
Thanks
UPDATE
The first error says: "The name 'InterpolationMode' does not exist in the current context"
The second error when i comment this line out is: 'NullReferenceException was unhandled "Object reference not set to an instance of an object.' on the line Bitmap bm = new Bitmap(img, Convert.ToInt32(img.Width * size.Width), Convert.ToInt32(img.Height * size.Height));
Thanks
Include
using System.Drawing.Drawing2D;
in your using list.
The second error could be due to either the img being null or the size being null.
The first compiler error is more than likely caused by an unknown reference to InterpolationMode.HighQualityBicubic. The InterpolationMode enumeration is found in the Drawing2D namespace, which is a child namespace of System.Drawing.
You can fix this error either by adding an additional Using directive for System.Drawing.Drawing2D, or by fully qualifying the namespace in your code:
grap.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic;
The second problem with your code is that the image you're specifying as a parameter to this method (img) is a null reference. The Scroll event of your zoom slider is probably getting raised as soon as the control is created (in your form's constructor), which is before the code in your form's Load method is run, which is what creates the image (by loading it from a file on disk).
Try adding a null check to the Scroll event handler:
private void zoomSlider_Scroll(object sender, EventArgs e)
{
if ((zoomSlider.Value > 0) && (imgOriginal != null))
{
picBox.Image = null;
picBox.Image = PictureBoxZoom(imgOriginal, new Size(zoomSlider.Value, zoomSlider.Value));
}
}
Finally, I noticed that you're setting the BackgroundImageLayout property of the picture box, but none of the code you post is actually specifying a background image for the picture box. Did you mean to set the SizeMode property to adjust how the image is displayed? Something like:
picBox.SizeMode = PictureBoxSizeMode.StretchImage;
Related
Basically i am trying to make a windows phone application where one by one images can be added on the canvas but the following code doesnt seem to work
private void AddImage_Click(object sender, RoutedEventArgs e)
{
PhotoChooserTask chooseImage = new PhotoChooserTask();
chooseImage.Completed += chooseImage_Completed;
chooseImage.Show();
}
public void chooseImage_Completed(object sender, PhotoResult e)
{
if (e.TaskResult != TaskResult.OK || e.ChosenPhoto == null)
{
return;
}
Image img = new Image();
SelectedBitmap = new WriteableBitmap(60,60);
img.Width = 100;
img.Height = 100;
img.Name = "img";
SelectedBitmap.SetSource(e.ChosenPhoto);
img.Source = SelectedBitmap;
e.ChosenPhoto.Position = 0;
CollageCanvas.Children.Add(img);
Canvas.SetTop(img,50);
Canvas.SetLeft(img,50);
}
the first time the button is clicked, image is successfully added to the canvas but when i attempt to add another image to the canvas it gives the following exception :-
"An exception of type 'System.ArgumentException' occurred in System.Windows.ni.dll but was not handled in user code
Additional information: Value does not fall within the expected range."
So i want to know how can i change my program to be able to add multiple images to the canvas.
I think it has something to do with the fact that the name property of each child element has to be unique. I think this should work for you.
private int index = 1;
public void chooseImage_Completed(object sender, PhotoResult e)
{
if (e.TaskResult != TaskResult.OK || e.ChosenPhoto == null)
{
return;
}
Image img = new Image();
WriteableBitmap SelectedBitmap = new WriteableBitmap(60, 60);
img.Width = 100;
img.Height = 100;
img.Name = "img";
SelectedBitmap.SetSource(e.ChosenPhoto);
img.Source = SelectedBitmap;
img.Name = "Photo " + index++; // Set unique name here
e.ChosenPhoto.Position = 0;
CollageCanvas.Children.Add(img);
Canvas.SetTop(img, 50);
Canvas.SetLeft(img, 50);
}
My form has two objects: a background image that takes up the entire screen, and a dragable dialog control that only takes up a portion of the screen. I am using Mouse events for dragging and dropping the dialog control within the background image.
My problem is that while dragging, there is a copy of the control that is visible at it's previous location.
What is causing this shadow copy to appear, and how can I prevent it from happening?
My code looks something like this:
private void dialog_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_dialogDragStart = e.Location;
dialog.MouseMove += new MouseEventHandler(dialog_MouseMove);
}
}
private void dialog_MouseUp(object sender, MouseEventArgs e)
{
dialog.MouseMove -= new MouseEventHandler(dialog_MouseMove);
_isDragging.Value = false;
}
private void dialog_MouseMove(object sender, MouseEventArgs e)
{
var difference = new Point(e.Location.X - _dialogDragStart.X, e.Location.Y - _dialogDragStart.Y);
if (!_isDragging.Value)
{
if (Math.Abs(difference.X) > SystemInformation.DragSize.Width || Math.Abs(difference.Y) > SystemInformation.DragSize.Height)
{
_isDragging.Value = true;
}
}
else if (_isDragging.Value && !difference.IsEmpty)
{
DialogOffset = GetValidDialogOffset(DialogOffset.X + difference.X, DialogOffset.Y + difference.Y);
this.Invalidate();
this.Update();
}
}
It should be noted that this entire UserControl contains a custom OnPaint event. The Paint event recalculates the Size and Location of the Dialog before painting it in a custom format. To get this working, I have simply adjusted the Location calculation to include the DialogOffset.
const int padding = 1;
const int shadowDepth = 3;
const int roudeCornerRadius = 5;
private void Paint(Graphics g, Rectangle clipRect)
{
try
{
dialog.Size = GetSize();
dialog.Location = new Point(
((backgroundImage.Width - dialog.Width) / 2) + DialogOffset.X,
((backgroundImage.Height - dialog.Height) / 2) + DialogOffset.Y);
if (Image != null && !backgroundImage.ClientRectangle.IsEmpty)
{
Rectangle imageBounds = new Rectangle(Point.Empty, Image.Size);
using (BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate(g, backgroundImage.ClientRectangle))
{
using (Bitmap img = ((Bitmap)backgroundImage).Clone(imageBounds, PixelFormat.Format16bppArgb1555) as Bitmap)
{
buffer.Graphics.Clear(Color.White);
buffer.Graphics.DrawImage(img,backgroundImage.ClientRectangle, imageBounds, GraphicsUnit.Pixel);
buffer.Render(g);
}
}
}
//Create Rectangles
Rectangle outerRect = dialog.ClientRectangle;
Rectangle innerRect = new Rectangle(padding, padding, outerRect.Width - (padding + shadowDepth), outerRect.Height - (padding + shadowDepth));
//create Paths
using (GraphicsPath innerPath = new GraphicsPath())
{
GraphicsHelper.GetRoundedRect(innerPath, innerRect, roudeCornerRadius, 1, 1);
//Assign outer rounded rectangle to the dialog's region property
Region region = new Region(innerPath);
if (dialog.Region != null)
dialog.Region.Dispose();
dialog.Region = region;
}
}
catch (Exception ex)
{
// Log error
}
}
I've seen suggestions to set the DoubleBufferred property to true, however its explicitly set to false in the existing code, and setting it to true causes no update at all while dragging.
I've tried taking a screenshot of the problem, however all screenshots only show one copy of the dialog control being dragged, even though I can clearly see a 2nd copy of the control on my screen while dragging.
What can be causing this, and how can I fix it?
I'm trying to make a puzzle game in microsoft visual c# 2010 and when I try to resize the image to fit the groupbox I get these errors:
error CS1502: The best overloaded method match for
'System.Drawing.Graphics.DrawImage(System.Drawing.Image,
System.Drawing.PointF)' has some invalid arguments
error CS1503: Argument 1: cannot convert from 'PuzzleImage.Form1' to
'System.Drawing.Image'
error CS1503: Argument 2: cannot convert from
'System.Drawing.Rectangle' to 'System.Drawing.PointF'
NOTE: The errors are in the 2nd part of the code, int the private Bitmap CreateBitmapImage(Form1 image) class.
Here is my code:
OpenFileDialog openFileDialog = null;
Form1 image;
PictureBox picBoxWhole = null;
private void buttonImageBrowse_Click(object sender, EventArgs e)
{
if (openFileDialog == null)
openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
System.Drawing.Image image = new Bitmap(openFileDialog.FileName);
if(picBoxWhole== null)
{
picBoxWhole= new PictureBox();
picBoxWhole.Height = groupboxPuzzle.Height;
picBoxWhole.Width =groupboxPuzzle.Width;
groupboxPuzzle.Controls.Add(picBoxWhole);
}
picBoxWhole.Image= image;
}
}
private Bitmap CreateBitmapImage(Form1 image)
{
Bitmap objBmpImage = new Bitmap(groupboxPuzzle.Width, groupboxPuzzle.Height);
Graphics objGraphics = Graphics.FromImage(objBmpImage);
objGraphics.Clear(Color.White);
int x = groupboxPuzzle.Width;
int y = groupboxPuzzle.Height;
objGraphics.DrawImage(image, new Rectangle(0,0, x, y));
objGraphics.Flush();
return objBmpImage;
}
And here is the tutorial that I am currently following. Also someone said something about an error at 77 step too.
Why are you transferring a Form parameter in your CreateBitmapImage() function? It says in that tutorial to accept Image type parameter.
private Bitmap CreateBitmapImage(Image image)
you need to change
Form1 image; to Image image; //only if you need this :)
and
private Bitmap CreateBitmapImage(Form1 image) to private Bitmap CreateBitmapImage(Image image)
I have created a function that loops a folder and retrieves each image file and draw a picturebox on the form.
Here is the function :
private void Create_Controls(string Img_path)
{
PictureBox p = new PictureBox();
p.Size = new Size(138, 100);
p.Location = new Point(6, 6);
p.BackgroundImage = Image.FromFile(Img_path);
p.BackgroundImageLayout = ImageLayout.Stretch;
this.Controls.Add(p);
}
So what i need to do is : whenever i click on any picturebox on the form , a message popup with the image file path.
So i thought about adding a custom event :
p.Click += delegate { Pop_Up(); };
AND
private void Pop_Up()
{
/* POP UP MESSAGE WITH Picturebox image file path*/
}
You need to use the property ImageLocation of the PictureBox . The property gets or sets the path or URL for the image to display in the PictureBox.
Just do the following:
p.Click += new EventHandler(Pop_Up);
...
private void Pop_Up(object sender, EventArgs e)
{
var pb = sender as PictureBox;
if(pb != null)
MessageBox.Show(pb.ImageLocation);
}
You could use Tag property for this.
something like this .
private void Create_Controls(string Img_path)
{
PictureBox p = new PictureBox();
p.Size = new Size(138, 100);
p.Location = new Point(6, 6);
p.Tag = Img_path;
p.BackgroundImage = Image.FromFile(Img_path);
p.BackgroundImageLayout = ImageLayout.Stretch;
this.Controls.Add(p);
}
private void Pop_Up()
{
MessageBox.Show(p.Tag);
}
For more on this Go here.
Then along with what HatSoft says, change your Pop_up() method like:
private void Pop_Up(object sender, EventArgs e)
{
MessageBox.Show(((PictureBox)sender).ImageLocation);
}
But maybe a bit more elegant and checking if it is indeed a PictureBox etc.
How can I center an image in a picturebox as I resize the form? What I have is a picturebox in a panel so if the image is larger than the picturebox, I can get scrollbars on the panel. But this doesn't work with the picturebox size mode "Center Image" and only works with "Auto Size".
This can easily be done with the SizeMode property
pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
Don't use a PictureBox here, a Panel is already perfectly capable of displaying a centered image through its BackgroundImage property. All that's needed is to turn on its DoubleBuffered property to suppress flicker. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form, replacing the panel. Assign its BackgroundImage property with the Properties window or in your code.
using System;
using System.Drawing;
using System.Windows.Forms;
internal class PicturePanel : Panel {
public PicturePanel() {
this.DoubleBuffered = true;
this.AutoScroll = true;
this.BackgroundImageLayout = ImageLayout.Center;
}
public override Image BackgroundImage {
get { return base.BackgroundImage; }
set {
base.BackgroundImage = value;
if (value != null) this.AutoScrollMinSize = value.Size;
}
}
}
What's wrong with using Padding?
void picturebox_Paint(object sender, PaintEventArgs e)
{
int a = picturebox.Width - picturebox.Image.Width;
int b = picturebox.Height - picturebox.Image.Height;
Padding p = new System.Windows.Forms.Padding();
p.Left = a / 2;
p.Top = b / 2;
picturebox.Padding = p;
}