panel to Imagelist in C# - c#

Hello friends i want to create new bitmap image of panel and want to store it in the imagelist and when the controls in the panel gets changed i want the image with different name and to be added to the image list and here goes my code for this.
private void button5_Click(object sender, EventArgs e)
{
var listViewItem = listView2.Items.Add(label1.Text);
Bitmap bm = new Bitmap(panel3.Size.Width, panel3.Size.Height);
panel3.Refresh();
panel3.DrawToBitmap(bm, new Rectangle(0, 0, panel3.Size.Width, panel3.Size.Height));
imageList1.Images.Add("1", bm);
listViewItem.ImageKey = "1";
}

You should keep a variable to determine the name every time you add one.
This sample keeps a variable at class level (nextImageNumber) which value is raised with 1 every time you generate a bitmap:
int nextImageNumber = 1;
private void button5_Click(object sender, EventArgs e)
{
var listViewItem = listView2.Items.Add(label1.Text);
Bitmap bm = new Bitmap(panel3.Size.Width, panel3.Size.Height);
panel3.Refresh();
panel3.DrawToBitmap(bm, new Rectangle(0, 0, panel3.Size.Width, panel3.Size.Height));
string name = nextImageNumber.ToString();
imageList1.Images.Add(name, bm);
listViewItem.ImageKey = name;
nextImageNumber++;
}

Related

how can I select the pictures loaded in windows Form in c#?

I have some pictures in a database which I retrieve them . To load these pictures, I made a "Tab Control" in Windows Form, which has a "Tab page1". when the program runs, a group box, containing a PictureBox (and some other text boxes), will be created for each picture. my pictures can be load in these picture boxes, and I will have a list of group boxes(gbList). However, I can not select these pictures during the run. Can anybody suggest a solution?
private void Form2_Load(object sender, EventArgs e)
{
tabPage1.Controls.Clear();
int x = 0, y = 0;
int j = 0;
for (int i = 0; i < output.Count - 1; i++)
{
PictureBox pic = new PictureBox();
pic.SizeMode = PictureBoxSizeMode.StretchImage;
SelectablegroupBox gb = new SelectablegroupBox();
gb.Controls.Add(pic);
gbList.Add(gb);
//to retrieve the images from the database in ProductImages class: (output is the result of a query of database)
ProductImages pI = output[i];
imgbyte = pI.Pic;
using (MemoryStream ms = new MemoryStream(imgbyte))
{
Image img = Image.FromStream(ms);
pic.Image = img;
}
//to add the group box list o the tabpage:
tabPage1.Controls.Add(gbList[j]);
gbList[j].Location = new Point(x, y);
y += gbList[i].Height;
j++;
}
here is my problem. I want the user to be able to select the images (Then I want to save these selected Items). But the "result" is always empty:
var result = from s in gbList
where s.Focused ==true
select s;
foreach (var s in result)
{ //save the selected images}
As I learned from another post, I defined SelectablegroupBox" as:
class SelectablegroupBox : GroupBox
{
public SelectablegroupBox()
{
this.SetStyle(ControlStyles.Selectable, true);
this.TabStop = true;
}
protected override void OnEnter(EventArgs e)
{
this.Focus();
this.Invalidate();
base.OnEnter(e);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
if (this.Focused)
{
var rc = this.ClientRectangle;
rc.Inflate(-2, -2);
ControlPaint.DrawFocusRectangle(pe.Graphics, rc);
}
}
}
thanks in advance
Your class SelectableGroupBox is not suitable to let the user select one or more images. There can be at most one focused control in your app - this will be probably a button on your form which the user clicks to save the selected images.
One simple solution would be to use CheckBox controls with the Appearance property set to Button. Also, you don't have to layout the images manually, let a FlowLayoutPanel do the job.
First, add a FlowLayoutPanel named flowLayoutPanel to your tabPage2 and set the following Properties:
flowLayoutPanel.AutoScroll = true;
flowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
Then change the appropriate code in Form2 to:
private const int imageWidth = 128;
private const int imageHeight = 128;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
for (int i = 0; i < output.Count; i++)
{
CheckBox cb = new CheckBox();
cb.Appearance = Appearance.Button;
cb.Size = new Size(imageWidth, imageHeight);
cb.BackgroundImageLayout = ImageLayout.Zoom;
ProductImages pI = output[i];
//Don't dispose the MemoryStream, the Image class will need it!
var ms = new MemoryStream(pI.Pic);
cb.BackgroundImage = Image.FromStream(ms);
flowLayoutPanel.Controls.Add(cb);
}
}
This is how you get your selected pictures:
private void SaveButton_Click(object sender, EventArgs e)
{
var selected = flowLayoutPanel.Controls.OfType<CheckBox>().Where(x => x.Checked);
Debug.Print("Selected images: {0}", selected.Count());
foreach (var item in selected)
{
//Save the picture from item.BackgroundImage.
}
}

c# VideoFileWriter properties

I want to record my screen while using my program.
Now I am using this code:
recorder.Open(pathFolder+GetCurrentDateAndTime() + ".mp4", Convert.ToInt32(System.Windows.SystemParameters.PrimaryScreenWidth), Convert.ToInt32(System.Windows.SystemParameters.PrimaryScreenHeight), 10, VideoCodec.MPEG4, 2000000);
The record is good but it's too fast.
What should I change to prevent it to be too fast and to be in normal speed?
First of all, initialize a timer control and assign properties to the control. Then, create a tick event to that timer.
videoTimer = new Timer(); videoTimer.Interval = 20;
videoTimer.Tick += videoTimer_Tick;
vfWriter = new VideoFileWriter(); vfWriter.Open("Exported_Video.avi", 800, 600, 25, VideoCodec.MPEG4, 1000000);
Then create a start button to start the timer.
private void btnStart_Click(object sender, EventArgs e) { videoTimer.Start(); }
In the timer tick event, create a bitmap image from the size of VideoFileWriter and capture screen and write it to bitmap image. Then, write the image to VideoFileWriter.
private void videoTimer_Tick(object sender, EventArgs e){bp = new Bitmap(800, 600); gr = Graphics.FromImage(bp);gr.CopyFromSceen(0, 0, 0, 0, new Size(bp.Width, bp.Height));
pictureBox1.Image = bp;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
vfWriter.WriteVideoFrame(bp);
}
In the end create a stop button to stop the timer and save the file.
private void btnStop_Click(object sender, EventArgs e){ videoTimer.Stop();vfWriter.Close();}

Dynamically creating a picturebox from another class into a form

I'm having troubles with this part trying to create a picturebox into another form from another class, i hope I've provided enough information c:
Catelogue.cs <-- class that loads the picturebox
class Catelogue
{
public void loadCatelogue()
{
mainPageGUI u = new mainPageGUI();
PictureBox pictureBox1 = new PictureBox();
pictureBox1.Location = new System.Drawing.Point(0, 0);
pictureBox1.Name = "pictureBox1";
pictureBox1.Size = new System.Drawing.Size(500, 500);
pictureBox1.BackColor = Color.Red;
u.Controls.Add(pictureBox1);
MessageBox.Show("HI");
}
}
mainmenuGUI.cs < --- form that's calling loadcatelogue() to load picturebox
private void catelogueButton_Click(object sender, EventArgs e)
{
Catelogue a = new Catelogue();
a.loadCatelogue();
}
You are creating a new instance of the mainPageGUI form and add, to that instance, the new picturebox. This instance is not the one that calls your method and it is never showed. So your original instance remain unchanged and you don't see anything. (Just to demonstrate the problem try to change your MessageBox line with u.Show();)
To fix, just change your calling code and pass the form instance on which the picturebox should be created
private void catelogueButton_Click(object sender, EventArgs e)
{
Catelogue a = new Catelogue();
// pass this instance to the method....
a.loadCatelogue(this);
}
and of course use the instance passed
public void loadCatelogue(mainPageGUI u)
{
PictureBox pictureBox1 = new PictureBox();
pictureBox1.Location = new System.Drawing.Point(0, 0);
pictureBox1.Name = "pictureBox1";
pictureBox1.Size = new System.Drawing.Size(500, 500);
pictureBox1.BackColor = Color.Red;
u.Controls.Add(pictureBox1);
}

print form on the full page instead of a part of it

i want to print my form on the whole page but instead the picture looks like this :
http://i.stack.imgur.com/JSXh2.jpg
it looks very small that's why i need the form to be printed on the whole full page
here is my code :
private void button5_Click(object sender, EventArgs e)
{
CaptureScreen();
printDocument1.Print();
}
private Bitmap _memoryImage;
private void CaptureScreen()
{
// put into using construct because Graphics objects do not
// get automatically disposed when leaving method scope
using (var myGraphics = CreateGraphics())
{
var s = Size;
_memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
using (var memoryGraphics = Graphics.FromImage(_memoryImage))
{
memoryGraphics.CopyFromScreen(Location.X, Location.Y, 0, 0, s);
}
}
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
var wScale = e.MarginBounds.Width / (float)_memoryImage.Width;
var hScale = e.MarginBounds.Height / (float)_memoryImage.Height;
// choose the smaller of the two scales
var scale = wScale < hScale ? wScale : hScale;
// apply scaling to the image
e.Graphics.ScaleTransform(scale, scale);
// print to default printer's page
e.Graphics.DrawImage(_memoryImage, 0, 0);
}
your help would be appreciated
try this to make a bitmap of your form:
Bitmap bm = new Bitmap(f1.Width, f1.Height);
this.DrawToBitmap(bm, new Rectangle(f1.Location, f1.Size));
maybe that's the problem! Report back if it works!
If you want to print it in landscape format than you have to rotate your bitmap using:
public Bitmap rotateInternalFunction(Bitmap bitmap)
{
bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
return bitmap;
}

Image Slider in C#?

I want to create a simple image slideshow, when the timer switch, it will switch to the next index of the picturebox (and will loop) but with a fade effect. How can it be done in C#?
Current Code doesn't switch images? And also - how can I create the fade ffect?
I created a simple timer with 5,000ms interval, enabled it on start.
private void timerImage_Tick(object sender, EventArgs e)
{
if (pictureBox1.Image.Equals(InnovationX.Properties.Resources._1))
{
pictureBox1.Image = InnovationX.Properties.Resources._2;
}
else if (pictureBox1.Image.Equals(InnovationX.Properties.Resources._2))
{
pictureBox1.Image = InnovationX.Properties.Resources._3;
}
else
{
pictureBox1.Image = InnovationX.Properties.Resources._1;
}
}
You can't compare Bitmap loaded from resource in this manner. Every time you get image from resource (in your case using property InnovationX.Properties.Resources._1) you will get new instance of Bitmap class. Comparing two different instances of Bitmap classes will always result in false, even if they contains same image.
Bitmap a = InnovationX.Properties.Resources._1; // create new bitmap with image 1
Bitmap b = InnovationX.Properties.Resources._1; // create another new bitmap with image 1
bool areSameInstance = a == b; // will be false
If you load you images from resources to member variables (e.g. in Load event).
// load images when you create a form
private Bitmap image1 = InnovationX.Properties.Resources._1;
private Bitmap image2 = InnovationX.Properties.Resources._2;
private Bitmap image3 = InnovationX.Properties.Resources._3;
// assing and compare loaded images
private void timerImage_Tick(object sender, EventArgs e)
{
if (pictureBox1.Image == image1)
{
pictureBox1.Image = image2;
}
else if (pictureBox1.Image == image2)
{
pictureBox1.Image = image3;
}
else
{
pictureBox1.Image = image1;
}
}
And after that, rewrite that code using array :)
Image[] images = new {
InnovationX.Properties.Resources._1,
InnovationX.Properties.Resources._2,
InnovationX.Properties.Resources._3
};

Categories