draw and move a rectangle over a bitmap

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

draw and move a rectangle over a bitmap

Postby mark_c » Mon Sep 17, 2018 7:18 am

Hello,
I can not find an example to draw and move a rectangle over a bitmap.
I have to have an Image1 that contains the bitmap and an Image2 that contains the fixed rectangle, even when the bitmap changes in the Image1; in short, a kind of sumulation of layers

example: Image

Code: Select all
void __fastcall TForm1::Button5Click(TObject *Sender)
{
        Image1->Picture->LoadFromFile("mypicture.jpg");
        bmp1= new Graphics::TBitmap;
        bmp1->Assign(Form1->Image1->Picture->Graphic);

        Image1->Picture->Bitmap->Assign(bmp1);
        delete bmp1;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
        if(Shift.Contains(ssLeft))
        {
                Label7->Caption=X;
                Label8->Caption=Y;
        }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Image1MouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
        Label4->Caption=X;
        Label5->Caption=Y;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Image1MouseUp(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
        int x1, y1, x2, y2;
        x1=StrToInt(Label4->Caption);
        y1=StrToInt(Label5->Caption);
        x2=StrToInt(Label7->Caption);
        y2=StrToInt(Label8->Caption);

        Image2->Transparent=true;
        Image2->Canvas->Pen->Color=clBlack;
        Image2->Picture->Bitmap->Canvas->Rectangle(x1,y1,x2,y2);
}
//---------------------------------------------------------------------------
mark_c
BCBJ Guru
BCBJ Guru
 
Posts: 129
Joined: Thu Jun 21, 2012 1:13 am

Re: draw and move a rectangle over a bitmap

Postby HsiaLin » Mon Sep 17, 2018 2:28 pm

You probably want to look into the LineDDA function.
It can draw the "marching ants" type selection rectangle that most image editing
programs use, but it is a little complicated.
HsiaLin
BCBJ Master
BCBJ Master
 
Posts: 299
Joined: Sun Jul 08, 2007 6:29 pm

Re: draw and move a rectangle over a bitmap

Postby rlebeau » Mon Sep 17, 2018 4:00 pm

mark_c wrote:Hello,
I can not find an example to draw and move a rectangle over a bitmap.
I have to have an Image1 that contains the bitmap and an Image2 that contains the fixed rectangle, even when the bitmap changes in the Image1; in short, a kind of sumulation of layers


I would not use TImage for this, especially when moving pieces around is involved. Use TPaintBox instead, and draw everything you need in its OnPaint event. Draw the bitmap first, and then draw the box on top of it. When you need to move things around, calculate what you need and then call the TPaintBox::Invalidate() method to trigger the OnPaint event, when can then redraw everything using the updated values as needed.

For example:

Code: Select all
private
    TJPEGImage *jpg;
    TPoint anchorPt;
    TRect box;

__fastcall TForm1::TForm1(TComponent *Owner)
    : TForm(Owner)
{
    anchorPt = Point(-1, -1);
    jpg = new TJPEGImage;
}

__fastcall TForm1::~TForm1()
{
    delete jpg;
}

void __fastcall TForm1::Button5Click(TObject *Sender)
{
    jpg->LoadFromFile("mypicture.jpg");
    PaintBox1->Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
    if (Shift.Contains(ssLeft))
    {
        if (X < anchorPt.X)
        {
            box.Left = X;
            box.Right = anchorPt.X;
        }
        else
        {
            box.Left = anchorPt.X;
            box.Right = X;
        }

        if (Y < anchorPt.Y)
        {
            box.Top = Y;
            box.Bottom = anchorPt.Y;
        }
        else
        {
            box.Top = anchorPt.Y;
            box.Bottom = Y;
        }

        PaintBox1->Invalidate();
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
    if (Button == mbLeft)
    {
        anchorPt = Point(X, Y);
        box = Rect(X, Y, X, Y);
        PaintBox1->Invalidate();
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Image1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
    if (Button == mbLeft)
    {
        anchorPt = Point(-1, -1);
        PaintBox1->Invalidate();
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
{
    PaintBox1->Canvas->FillRect(PaintBox1->ClientRect);

    if (!jpg->Empty)
        PaintBox1->Canvas->Draw(0, 0, jpg);

    if (!box.IsEmpty())
    {
        PaintBox1->Canvas->Pen->Color = clBlack;
        PaintBox1->Canvas->Brush->Style = bsClear;
        PaintBox1->Canvas->Rectangle(box);
    }
}
//---------------------------------------------------------------------------
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1533
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: draw and move a rectangle over a bitmap

Postby mark_c » Tue Sep 18, 2018 8:30 am

thanks for now
mark_c
BCBJ Guru
BCBJ Guru
 
Posts: 129
Joined: Thu Jun 21, 2012 1:13 am

Re: draw and move a rectangle over a bitmap

Postby mark_c » Fri Sep 21, 2018 9:19 am

this is my modified version that I leave to thank the staff. It basically restores the bitmap through bmp2 to every redraw of the rectangle. I hope it can serve others.

Code: Select all
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <Jpeg.hpp>

Graphics::TBitmap *bmp1, *bmp2;

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
        DoubleBuffered=true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
        Image1->Picture->LoadFromFile("mypicture.jpg");
        bmp1= new Graphics::TBitmap;
        bmp2= new Graphics::TBitmap;
        bmp1->Assign(Form1->Image1->Picture->Graphic);

        Image1->Picture->Bitmap->Assign(bmp1);
        bmp2->Assign(bmp1);
        delete bmp1;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Image1MouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
        Label1->Caption=X;
        Label2->Caption=Y;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
        if(Shift.Contains(ssLeft))
        {
                Label3->Caption=X;
                Label4->Caption=Y;


                int x1, y1, x2, y2;
                x1=StrToInt(Label1->Caption);
                y1=StrToInt(Label2->Caption);
                x2=StrToInt(Label3->Caption);
                y2=StrToInt(Label4->Caption);

                if(x1 > x2 || y1 > y2) return;

                Image1->Picture->Bitmap->Assign(bmp2);

                Image1->Picture->Bitmap->Canvas->Brush->Style = bsClear;
                Image1->Picture->Bitmap->Canvas->Rectangle(x1,y1,x2,y2);
        }
}
//---------------------------------------------------------------------------
mark_c
BCBJ Guru
BCBJ Guru
 
Posts: 129
Joined: Thu Jun 21, 2012 1:13 am


Return to Technical

Who is online

Users browsing this forum: No registered users and 9 guests

cron