?
Solved

how to mask an image

Posted on 2001-09-05
19
Medium Priority
?
341 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 5
  • 2
  • +3
19 Comments
 
LVL 9

Expert Comment

by:ginsonic
ID: 6459484
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
ID: 6459505
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
ID: 6461182
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 34

Expert Comment

by:Slick812
ID: 6463018
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
ID: 6463640
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
ID: 6464142
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
ID: 6466053
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 34

Expert Comment

by:Slick812
ID: 6466271
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
ID: 6472342
>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
 
LVL 6

Expert Comment

by:edey
ID: 6472442
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
ID: 6472676
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
ID: 6487040
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
ID: 6487079
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
ID: 6487104
hello slick812

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

ws1999
0
 
LVL 34

Expert Comment

by:Slick812
ID: 6488168
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
ID: 6489121
hello slick812

can you explain more about the 1 bit bitmap definition?

i never heard about this.

ws1999
0
 
LVL 34

Expert Comment

by:Slick812
ID: 6490992
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 34

Accepted Solution

by:
Slick812 earned 450 total points
ID: 6492469
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
ID: 6621485
thanks

ws1999
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
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…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
Suggested Courses
Course of the Month14 days, 16 hours left to enroll

771 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