Solved

how to mask an image

Posted on 2001-09-05
19
328 Views
Last Modified: 2010-05-19
i want to create  mask tools to select some certain area in an image ,somewhat like photoshop, but i quite wonder how to do this.

Is anybody can give some hint as how to make a mask on an image,and what does it mean to the image,i think it is not drawed but.....

150pts for helpful answer.

ws1999
0
Comment
Question by:ws1999
  • 8
  • 5
  • 2
  • +3
19 Comments
 
LVL 9

Expert Comment

by:ginsonic
Comment Utility
I don't understand . You need a code to select a specified colir from areea ?
For example , you click on picture and select all pixels with same color form area ( not from entire picture) ?

Nick aka ginsonic
0
 

Author Comment

by:ws1999
Comment Utility
not only click but maybe press and drag for example to draw a unregular area as the selected area, i just want to select and make the program to remember the select.how to achieve it?

0
 
LVL 6

Expert Comment

by:edey
Comment Utility
if you've got an idea as to how to make the selection, then keeping it is easy - just fill in the selected areas on a 1 bit bit map.  Then you you want to draw the masked bitmap, do it with maskBlt.

GL
Mike
0
 
LVL 33

Expert Comment

by:Slick812
Comment Utility
hello ws1999, I'm not sure what you are asking for? ? you say "some hint as how to make a mask on an image", , , I don't know "mask on image"?  , , what is that you need code for? Code for drawing the outline as the mouse moves with the left button down ? or drawing on a 1 bit bitmap at the same time as you draw on the image to save the "selected area" ? ? or putting the saved area back on the image during a repaint? or using the 1 bit mask pic to mask the image durring an image lightening process or color change process?
0
 

Author Comment

by:ws1999
Comment Utility
hi Slick812

have you ever use photoshop or photopaint software, this software can use magicpen or someother tool to select an area in a picture,i want to create this kind of effect in my program.we call this as mask, that is all.can you offer me some help?

ws1999
0
 
LVL 3

Expert Comment

by:rondi
Comment Utility
The answer really depends on what you wanna do with the
selection.

You would need to store the selected pixels in some kinda
data structure - the structure would depend on what it'll
be used for.
To collect You could do something like:


type
  PPoint: ^TPoint;

TForm1 = class(TForm....

private
  FSelection: TList;

procedure FormCreate....
begin
  FSelection := TList.Create;
end;

procedure FormDestroy...
begin
  FSelection.Free;
end;

procedure Image1MouseDown(...X,Y.....
begin
  selecting := true;
  ClearSelection;
  AddToSelection(X,Y);
end;

procedure Image1MouseMove(...X,Y.....
begin
  if selecting then AddToSelection(X,Y);
end;

procedure Image1MouseUp(...X,Y.....
begin
  if selecting then selecting := false;
end;

procedure ClearSelection;
var
  ppt: PPoint;
  i:integer;
begin
  for i := 0 to FSelection.count-1 do
  begin
    ppt := FSelection[i];
    Dispose(ppt);
  end;
  FSelection.Clear;
end;

procedure AddToSelection(const sx,sy: integer);
var
  ppt: PPoint;
begin
  if Selected(sx,sy) then exit;
  New(ppt);
  ppt^.X := sx;
  ppt^.Y := sy;
  FSelection.Add(ppt);
end;

function Selected(const sx,sy: integer): boolean;
var
  ppt: PPoint;
  i:integer;
begin
  Result := false;
  for i := 0 to FSelection.count-1 do
  begin
    ppt := FSelection[i];
    if (ppt^.X = sx) and (ppt^.Y = sy) then
    begin
      Result := true;
      exit;
    end;
  end;
end;
0
 

Author Comment

by:ws1999
Comment Utility
Hello,Rondy

yes your answer is very helpful, one more thing is how can i make the slelection visible on the picture,that is customer can see it from surface like photoshop, not just store in.

any further help?

ws1999
0
 
LVL 33

Expert Comment

by:Slick812
Comment Utility
I have used many graphics editing software programs, and I know about a graphic "mask" very well. But there is NO MASK until you develop programing code to do something to the image pixel structure (bitmap array of pixels) and then have the changes apply to portions of the that image and NOT apply to other portions of the image. Otherwise it is just some lines drawn on your image. So you have not said what image transformations (lighten, darken, contrast, adjust color (RGB) intensities, or many others) that you might want to "mask" the image from.. . . You say "i want to create this kind of effect in my program" and before that you say "use magicpen or someother tool", these tools are not all the same and would use compleatly different code.
Even just the magic pen tool might take alot of code to correctly get the pixels that are within a certain color value. Here is some code to draw a "mask" on a paintBox Imageand create a 1 bit Select area bitmap. I use a PaintBox because it is easier to draw on without flicker.

 - - - - - - - - - - - - - - - - - - - - - - - -

unit select1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Buttons, StdCtrls, ExtCtrls, ExtDlgs, Math;

type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    but_LoadBit: TButton;
    sbut_SelNone: TSpeedButton;
    sbut_SelAll: TSpeedButton;
    OpenPicDia1: TOpenPictureDialog;
    SavePictureDialog1: TSavePictureDialog;
    sbut_SaveBit: TSpeedButton;
    but_Exit: TButton;
    sbut_SeeSelect: TSpeedButton;
    Label1: TLabel;
    procedure PaintBox1Paint(Sender: TObject);
    procedure but_ExitClick(Sender: TObject);
    procedure but_LoadBitClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure sbut_SelAllClick(Sender: TObject);
    procedure sbut_SelNoneClick(Sender: TObject);
    procedure sbut_SeeSelectClick(Sender: TObject);
  private
    { Private declarations }
    BasePic, SelectPic: TBitmap;
    StartX, StartY, LastX, LastY, MinX, MaxX, MinY, MaxY: Integer;
    DrawIt: Boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
DrawIt := False;
StartX := 1;
StartY := 1;
LastX:= 1;
LastY := 1;
MinX := 0;
MaxX := 0;
MinY := 0;
MaxY := 0;
BasePic := TBitmap.Create;
BasePic.Width := PaintBox1.Width;
BasePic.Height := PaintBox1.Height;
SelectPic := TBitmap.Create;
{SelectPic is the 1 bit bitmap with the selected area that can be used
to limit the Image changes to that area}
SelectPic.Width := BasePic.Width;
SelectPic.Height := BasePic.Height;
SelectPic.PixelFormat := pf1bit;
PaintBox1.Canvas.Pen.Style := psSolid;
PaintBox1.Canvas.Pen.Mode := pmNot;
{use the pmNot Mode to make sure you can see the pen on any color}
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
PaintBox1.Canvas.Draw(0,0,BasePic);
end;

procedure TForm1.but_ExitClick(Sender: TObject);
begin
Close;
end;

procedure TForm1.but_LoadBitClick(Sender: TObject);
begin
if OpenPicDia1.Execute then
  begin
  try
    BasePic.LoadFromFile(OpenPicDia1.FileName);
    except
      on E: Exception do
        begin
        ShowMessage('the file - '+OpenPicDia1.FileName+' - is an Ivalid Graphic');
        Exit
        end;
  end; //try
If (BasePic.Width < 461) and (BasePic.Height < 345) then
  begin
  PaintBox1.Width := BasePic.Width;
  PaintBox1.Height := BasePic.Height;
  SelectPic.Width := BasePic.Width;
  SelectPic.Height := BasePic.Height;
  end else
  ShowMessage('the bitmap file - '+OpenPicDia1.FileName+' - is too large to fit');
end;
end;

procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
PBrect: TRect;
begin
StartX := X;
StartY := Y;
PaintBox1.Canvas.Draw(0,0,BasePic);
PBrect := PaintBox1.ClientRect;
PBrect := Rect(PBrect.Left,PBrect.Top+PaintBox1.Top,PBrect.Right,PBrect.Bottom+PaintBox1.Top);
PBrect.TopLeft := ClientToScreen(PBrect.TopLeft);
PBrect.BottomRight := ClientToScreen(PBrect.BottomRight);
ClipCursor(@PBrect);
{ClipCursor prevents the cursor from going out of the paintbox while drawing}
PaintBox1.Canvas.MoveTo(X,Y);
SelectPic.Canvas.Brush.Color := clWhite;
SelectPic.Canvas.FillRect(PaintBox1.ClientRect);
{The SelectPic is erased on a mouse down}
SelectPic.Canvas.Pen.Style := psSolid;
SelectPic.Canvas.Pen.Color := clBlack;
SelectPic.Canvas.MoveTo(X,Y);
DrawIt := True;
LastX := X;
LastY := Y;
  MinX := 32000;
  MaxX := 0;
  MinY := 32000;
  MaxY := 0;
end;

procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
CenterX, CenterY: Integer;
begin
ClipCursor(nil);
PaintBox1.Canvas.LineTo(StartX, StartY);
SelectPic.Canvas.LineTo(StartX, StartY);
DrawIt := False;
CenterX := (MinX+MaxX) div 2;
CenterY := (MinY+MaxY) div 2;
Label1.Caption := 'MinY: '+IntToStr(MinY)+' MaxY: '+IntToStr(MaxY)+' MinX: '+IntToStr(MinX)+' MaxX: '+IntToStr(MaxX);
SelectPic.Canvas.Brush.Color := clBlack;
SelectPic.Canvas.FloodFill(CenterX,CenterY,clWhite,fsSurface);
{this is an easy way to fill the Selected area, it wll only work on simple
areas where the lines never cross, but it needs alot more code to
correctly fill complex areas}
end;

procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
if DrawIt then
  begin
  PaintBox1.Canvas.MoveTo(LastX,LastY);
  PaintBox1.Canvas.LineTo(X,Y);
  SelectPic.Canvas.LineTo(X,Y);
  LastX := X;
  LastY := Y;
  MinX := Min(MinX,X);
  MinY := Min(MinY,Y);
  MaxX := Max(MaxX,X);
  MaxY := Max(MaxY,Y);
  end;
end;

procedure TForm1.sbut_SelAllClick(Sender: TObject);
begin
{select ALL of the Image}
PaintBox1.Canvas.Brush.Style := bsClear;
PaintBox1.Canvas.Rectangle(PaintBox1.ClientRect);
end;

procedure TForm1.sbut_SelNoneClick(Sender: TObject);
begin
{Select NONE of the Image}
PaintBox1.Canvas.Draw(0,0,BasePic);
end;

procedure TForm1.sbut_SeeSelectClick(Sender: TObject);
begin
{click this to see the 1 bit SelectPic of the selected area in
the PaintBox}
PaintBox1.Canvas.Draw(0,0,SelectPic);
end;

end.

 - - - - - - - - - - - - - - - - - - -

this will draw on the painbox as you move the mouse. hope this gives you some idea, let me know
0
 
LVL 26

Expert Comment

by:EddieShipman
Comment Utility
>have you ever use photoshop or photopaint software, this
>software can use magicpen or someother tool
>to select an area in a picture,i want to create this kind
>of effect in my program.we call this as mask,
>that is all.can you offer me some help?

Well, you are calling it the wrong thing, then. This is
a SELECTION, NOT a MASK. Note the word above "select"

A mask is used to hide portions of your image from view to
allow portions of other images to be displayed. The mask
hides the portion of the image by introducing levels of
transparency. The transparency information is defined
using greyscale information.

In order to implement marquee selection, you need an edge
detection algorithm. There is a current thread concerning
this in the borland.public,delphi.objectpascal newsgroup at
forums.borland.com titled "Graphics Outline".

There was some code posted there but it uses the very slow
pixels routines to detect. I'd suggest modifying it to
use scanline.



0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 6

Expert Comment

by:edey
Comment Utility
rather then a complicated edge detection you _could_ use a mask. To copy the selection you'd actually copy the rectangle defining the bounding rect of the selction (the smallest rectangle that includes the entire selection) & keep the 1 bit mask.  The selection is then the combination of the two.

GL
Mike
0
 
LVL 26

Expert Comment

by:EddieShipman
Comment Utility
or... use the same algorithm I use in my
Complex Window Regions article at:

http://www.undu.com/Articles/990114c.html



0
 

Author Comment

by:ws1999
Comment Utility
hello slick812

the code you offered  have been used in my new project, but why there is no effect when loading a picture?

i cannot see the picture in the paintbox.

ws1999
0
 

Author Comment

by:ws1999
Comment Utility
hello slick812

sorry i made some mistake, now it work well but one more thing, there is a sbut_SaveBit(Speed Button) in the form ,but there is no code about it,why?

thanks for your code

ws1999
0
 

Author Comment

by:ws1999
Comment Utility
hello slick812

yes,that is really i want ,how to save the selection?

ws1999
0
 
LVL 33

Expert Comment

by:Slick812
Comment Utility
OK, the bitmap SelectPic has a graphical representation of your Selected area (but it is not a "selected area", which you will have to define in code). . . . to save this SelectPic to file use the standard SelectPic.SaveToFile('SelArea.bmp') . . . . . you can use this 1bit bitmap as a "Mask" in some drawing functions, so it will be a mask in that case.
0
 

Author Comment

by:ws1999
Comment Utility
hello slick812

can you explain more about the 1 bit bitmap definition?

i never heard about this.

ws1999
0
 
LVL 33

Expert Comment

by:Slick812
Comment Utility
SelectPic.PixelFormat := pf1bit;
I put this in the bitmap SelectPic creation so it might be used as a "Mask" bitmap. Understanding bitmap pixel formats, pixel definition structures (1 bit, 4 bit, 8 bit, 24 bit) in bitmaps, and using these in code is a wide and long subject, which takes a long time and alot of study (for me anyway) to halfway understand. a short intro for you . . . . ,
A bitmap is an array of pixel color values (one value for each pixel in the bitmap), the pixel's color is defined by the amount of color info that is in each block of the array, (the color depth or pixel format is in the bitmap's file header). One bit is either On or Off (black or white, which means NO COLOR values except in the palette), 4 bit has 16 posible color values (red On or Off, green On or Off, blue On or Off, and "brightness" On or Off), 8 bit has One Byte for each pixel, and 24 bit has 3 Bytes for each pixel.
For a "Mask" bitmap all that is needed is a On or Off (black or white) value, so each pixel location is either "In" the Mask, or NOT. You will have to get a book or look to Info web sites for more about this, , , , it gets more complicated when you add palettes to it. I think that most everyone finds all of this difficult at first. hopes this helps
0
 
LVL 33

Accepted Solution

by:
Slick812 earned 150 total points
Comment Utility
sorry ws1999, I gave you some incorrect info, , , in a 4 bit bitmap the colors are in it's palette from 0 to 15 and the 4 bits of color info gives the number of the palette color, same in 8 bit where there are 256 palette colors and the byte of info gives the palette color number for that pixel, ,  A 4 or 8 bit bitmap can ONLY show the defined colors in it's palette. the 4 bit color info I gave before is for DOS 16 color display. Here is a link to some graphics info for Delphi at efg's , , , ,
http://www.efg2.com/Lab/Library/

and a link to computer color info at the same site, , ,
http://www.efg2.com/Lab/Library/Color/AndComputers.htm
0
 

Author Comment

by:ws1999
Comment Utility
thanks

ws1999
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now