Witam
Potrzebuje zrobić screenshota z calego ekranu do panela i sobie ramką zaznaczyć fragment po czym skopiować zaznaczony fragment do innej bitmapy żebym mógł to później wyświetlić na jakimś innym komponencie i sobie dalej obrabiać.
Program na razie robi screenshota za pomoca CopyFromScreen (no i właśnie chyba za pomocą tej metody nie da się skopiować fragmentu obrazka do innej bitmapy czy komponentu/Graphics-a ??? )
Nie bardzo rozumiem jak .NET się rozwiązuje problem ze zgodnością kontekstów graficznych. Załóżmy, że mam dwie bitmapy jedną większa druga mniejszą. Z tej większej chce skopiować fragment i wrzucić do tej mniejszej to jak to się robi?
W konstruktorze formy robie:
imgx = imgy = imgwidth = imgheight = 0;
image = ScreenShot();
imgwidth = image.Width;
imgheight = image.Height;
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
this.UpdateStyles();
Graphics g = this.CreateGraphics();
Rectangle screen = new Rectangle();
screen = Screen.PrimaryScreen.Bounds;
bitmapa = new Bitmap(screen.Width, screen.Height, g); // to na koncu tylko po to zeby bitmapa miała zgodna rozdziałkę?
Graphics bg = Graphics.FromImage(bitmapa); //rozumiem ze to FromImage przystosowuje kontekst bitmapy do Graphicsa?
bg.CopyFromScreen(0, 0, 0, 0, screen.Size); //rysuje mi ekran w pamięci-bitmapa btw wolałem stare dobre BitBlt();
W metodzie Paint dla panela mam:
e.Graphics.DrawImageUnscaled(bitmapa, new Point(0, 0));
//e.Graphics.CopyFromScreen(new Point(0, 0), new Point(100, 50),
//new Size(200, 100));
//if (skip) return;
//e.Graphics.DrawImage(image, new Rectangle(x--, 0, panel1.Width, panel1.Height), new Rectangle(imgx, imgy, panel1.Width, panel1.Height), GraphicsUnit.Pixel);
SolidBrush b = new SolidBrush(Color.FromArgb(0, 255, 0, 0));
Pen p = new Pen(Color.FromArgb(255, 255, 0, 0));
e.Graphics.DrawRectangle(p, rec);
Rysowanie ramki realizuje w ten sposób:
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
//Rysowanie ramki do zaznaczania pikseli - przekierowanie/blokada komunikatow myszki do panela
mouseDown = true;
pointPos = e.Location;
panel1.Capture = true;
rec.X = pointPos.X;
rec.Y = pointPos.Y;
rec.Width = 0;
rec.Height = 0;
panel1.Invalidate();
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
//Koniec rysowania ramki do zaznaczania pikseli, zwolnienie myszki
mouseDown = false;
panel1.Capture = false;
panel1.Tag = e;
panel1.Invalidate();
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
//Aktualizacja rozmiaru ramki(rectangla) i odrysowanie
if (mouseDown)
{
if (e.X > pointPos.X + rec.Width)
rec.Width += 1;
if (e.X < pointPos.X + rec.Width)
rec.Width -= 1;
if (e.Y > pointPos.Y + rec.Height)
rec.Height += 1;
if (e.Y < pointPos.Y + rec.Height)
rec.Height -= 1;
panel1.Invalidate();
}
private void button3_Click(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics();
Rectangle screen = new Rectangle();
screen = Screen.PrimaryScreen.Bounds;
bitmapa = new Bitmap(screen.Width, screen.Height, g);
bitmapa2 = new Bitmap(rec.Width, rec.Height, g);
g.Dispose();
bitmapa2 = bitmapa.Clone(rec, bitmapa.PixelFormat);
Graphics bg = Graphics.FromImage(bitmapa);
bg.CopyFromScreen(rec.X, rec.Y, 0, 0, rec.Size);
Graphics pgrap = pictureBox1.CreateGraphics();
pictureBox1.Image = bitmapa2;
//pgrap.DrawImageUnscaled(bitmapa2, 0, 0);
bg.Dispose();
}
Jak na razie z tego co mi przychodzi do głowy to jedynymi sposobami na skopiowanie jakiegoś fragmentu obrazka jest duet LockBits i BitmapData, czyli grzebanie na poszczególnych bitach bitmapy albo korzystanie z beznadziejnie wolnej metody GetPixel.