Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Opinions on best way to do this...

Posted on 2004-03-30
13
Medium Priority
?
202 Views
Last Modified: 2010-04-05
Hey gang,

I'm creating an application that will accompany a board game that some friends and I play.  Basically the application is to keep track of our map movements.

I have a HUGE image that has territories on it.  I want to be able to color those territories based on who owns them.  I had originally intended to do this via the web and just use HTML but it turned into a larger task and I think it requires an application of its own.  

My question is, what is the best way to individually color each territory.  Do I need to "cut" each territory into its own image, or is there a way I can overlay a color for that specific territory?  

Each map segment (territory) can be any random shape, sort of like the board game RISK.  Plus there can be hundreds of them..  A way to individually color them without having to resort to creating a colored image for each would be nice..

Thoughts?  Did I explain what I want well enough?

I use Delphi 5 btw..

Thanks guys.
0
Comment
Question by:Palamedes
[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
  • 5
  • 4
  • 3
  • +1
13 Comments
 
LVL 17

Expert Comment

by:mokule
ID: 10717609
Use
windows.CreatePolygonRgn
0
 
LVL 17

Expert Comment

by:mokule
ID: 10717653
Here is an example of painting
procedure TForm1.MOPaintBox1Paint(Sender: TObject);
var
  dc: HDC;
  br: HBRUSH;
  Index: integer;
  hr: HRGN;
  x,y: integer;
begin
  dc := MOPaintBox1.Canvas.Handle;
  if not bEmptyRgn then
    begin
    hr := CreateRectRgn(0,0,MOPaintBox1.Width,MOPaintBox1.Height);
    CombineRgn(hr,hr,hrd,RGN_DIFF);
    SelectClipRgn(dc,hr);
    end;
  MOPaintBox1.Canvas.Draw(0,0,imFoto.Picture.Graphic);

  SelectClipRgn(dc,hrd);
  if not bEmptyRgn then
    begin
    Index := ListBox1.ItemIndex;
    if Index >= 0 then
      begin
      x := 0;
      repeat
        y := 0;
        repeat
          imKostka.Canvas.Draw(x,y,TBitmap(ListBox1.Items.Objects[Index]));
          y := y + TBitmap(ListBox1.Items.Objects[Index]).Height-1;
        until y > imKostka.Picture.Height;
        x := x + TBitmap(ListBox1.Items.Objects[Index]).Width-1;
      until x > imKostka.Picture.Width;
      end;
    MOPaintBox1.Canvas.Draw(0,0,imKostka.Picture.Bitmap);
    end;
end;
0
 
LVL 17

Expert Comment

by:mokule
ID: 10717739
And region creation

procedure TForm1.MOPaintBox1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  hr: HRGN;
begin
  Xo := X;
  Yo := Y;
  Xp := X;
  Yp := Y;
  if tbDraw.Down then
    begin
    if ssLeft in Shift then
      begin
      if bDrawLine then
        begin
        if ilPun <= MAXPUN then
          begin
          tabPun[ilPun].x := X;
          tabPun[ilPun].y := Y;
          Inc(ilPun);
          end;
        end
      else
        begin
        bDrawLine := True;
        tabPun[0].x := X;
        tabPun[0].y := Y;
        ilPun := 1;
        end;
      end;
    if ssRight in Shift then
      begin
      if ilPun > 2 then
        begin
        if bEmptyRgn then
          begin
          hrd := CreatePolygonRgn(tabPun,ilPun,ALTERNATE);
          bEmptyRgn := False;
          end
        else
          begin
          hr := CreatePolygonRgn(tabPun,ilPun,ALTERNATE);
          bEmptyUndoRgn := False;
          CombineRgn(hru,hrd,hrd,RGN_OR);
          CombineRgn(hrd,hrd,hr,RGN_OR);
          end;
        end;
      bDrawLine := False;
      ilPun := 0;
      MOPaintBox1.Invalidate;
      end;
    end;
end;
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 11

Expert Comment

by:shaneholmes
ID: 10717792
Mokule is right, windows.CreatePolygonRgn is the way to go.

Do you plan on having one map or many?

If your maps are going to change, you might consider creating some kind of editor by which you can create your map region ploygons with.

I recommend you look at the following articles on www.delphizine.com;

Although they are not articles on painting regions, there is great information on how to create a ploygon region editor.

If you are not a member, you can create a free limited time membership.

Shane

Hot Spots: Part I
http://www.delphizine.com/features/2002/02/di200202vh_f/di200202vh_f.asp

Hot Spots: Part II
http://www.delphizine.com/features/2002/03/di200203vh_f/di200203vh_f.asp

0
 
LVL 4

Author Comment

by:Palamedes
ID: 10717852
Thanks guys.. I'll read those articles shaneholmes.

Mokule, I'm trying to use your snippets but getting all kinds of undeclared identifiers..
bEmptyRgn, hrd, imFoto, etc..

I'm guessing you pulled this from another application?
0
 
LVL 4

Author Comment

by:Palamedes
ID: 10717876
Shane,

How do I become a free limited time member to view those articles?  I don't want to have to pay if at all possible.
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10717975
You didn't hear this from me, but a little bird once told me that all you had to do was create a psuedo account using a free email address (i.e. yahoo, hotmail, etc) - <SMILE>

shane
0
 
LVL 17

Expert Comment

by:mokule
ID: 10718115
Sorry for some mess.
Yes of course it was cut from bigger application.
0
 
LVL 4

Author Comment

by:Palamedes
ID: 10718139
Thanks Shane  =)

One thing I don't think I made clear though in my original question..

I need to be able to color the individual sections..  They map sections have wonderful detail that I don't want to completely overwrite.. I just want to be able to give them a HUE of the color that owns them.. so some sort of opacity is needed here..  
0
 
LVL 17

Expert Comment

by:mokule
ID: 10718148
Here should be declaratons.
But now I'm not sure wether cut it from the same version.
My fault


{
type TUndo = record
  Xp,Yp: integer;
  Xk,Yk: integer;
  op:
  end;
  }
const
  MAXPUN = 100;

type
  TForm1 = class(TForm)
    ImageList1: TImageList;
    Panel1: TPanel;
    ListBox1: TListBox;
    Panel2: TPanel;
    ToolBar1: TToolBar;
    tbRect: TToolButton;
    tbEllipse: TToolButton;
    ToolButton3: TToolButton;
    StatusBar1: TStatusBar;
    Panel3: TPanel;
    MOPaintBox1: TMOPaintBox;
    Splitter1: TSplitter;
    tbNew: TToolButton;
    tbOpen: TToolButton;
    tbSave: TToolButton;
    ToolButton5: TToolButton;
    tbUndo: TToolButton;
    tbErase: TToolButton;
    ToolButton8: TToolButton;
    ToolButton1: TToolButton;
    tbDraw: TToolButton;
    tbFoto: TToolButton;
    opDlg: TOpenPictureDialog;
    imFoto: TImage;
    imKostka: TImage;

    procedure MOPaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure MOPaintBox1MouseLeave(Sender: TObject);
    procedure ListBox1DrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    procedure FormCreate(Sender: TObject);
    procedure MOPaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure MOPaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure MOPaintBox1Paint(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
    procedure tbNewClick(Sender: TObject);
    procedure tbEraseClick(Sender: TObject);
    procedure tbUndoClick(Sender: TObject);
    procedure tbFotoClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure tbDrawClick(Sender: TObject);
  private
    { Private declarations }
    bPocz: boolean;
    Xo,Yo: integer;
    Xp,Yp: integer;
    hrd: HRGN;
    hru: HRGN;
    bEmptyUndoRgn: boolean;
    bEmptyRgn: boolean;
    bDrawLine: boolean;
    tabPun: array[0..MAXPUN] of TPoint;
    ilPun: integer;
  public
    { Public declarations }
  end;
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10718200
Right, like I said, the links only describe how to create your own editor to load your image (map), and create a polygon region of your map, which you can use in your painting algorithm

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10718218
What I would do once you have the polygonal region of the map, is too create a algorithm which you can invert the color in that region .

Shane
0
 
LVL 2

Accepted Solution

by:
xxflip earned 500 total points
ID: 10724351
What I did was create the regions, and create a shaded area (Green, Red, Blue, Purple, Yellow, ...) of each one, depending on the player it belongs to.

here's the Unit (the bitmap for this example and a working demo can be requested from xxflip_pt@yahoo.com),


// -------------- UNIT1.PAS
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Buttons, jpeg;

type
  TForm1 = class(TForm)
    Img: TImage;
    BitBtn1: TBitBtn;
    chRed: TCheckBox;
    chGreen: TCheckBox;
    chBlue: TCheckBox;
    Label1: TLabel;
    procedure BitBtn1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    MyRegion:hRGN;
    originalImg:TBitmap;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
Var
  Points : Array[0..4] of TPoint;
begin
  //Keep a copy of the original
  Img.Picture.LoadFromFile('aa.bmp');
  originalImg:=TBitMap.Create;
  originalImg.Assign(Img.Picture.Bitmap);
  //Define Region 1
  //There are functions to get a region from a mask image
  Points[0].X := 56;  Points[0].Y := 149;
  Points[1].X := 151; Points[1].Y := 149;
  Points[2].X := 151; Points[2].Y := 282;
  Points[3].X := 113; Points[3].Y := 282;
  Points[4].X := 56;  Points[4].Y := 227;
  MyRegion:=CreatePolygonRgn(Points,5,Winding);
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
Var
  K,L:Integer;
  P:TColor;
begin
  For K := 0 to originalImg.Width do begin
    For L := 0 to originalImg.Height do begin
      //If pixel inside region then do the shading
      If PtInRegion(MyRegion,K, L) then begin
        P := originalImg.Canvas.Pixels[K, L];
        If chRed.Checked then P := (P and $FFFF00); //Red
        If chGreen.Checked then P := (P and $FF00FF); //Green
        If chBlue.Checked then P := (P and $00FFFF); //Blue
        Img.Canvas.Pixels[K, L] := P;
      end;
    end;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  originalImg.Free;
end;

end.


// -------------- UNIT1.DFM
object Form1: TForm1
  Left = 217
  Top = 106
  Width = 597
  Height = 381
  Caption = 'Region Shades'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Img: TImage
    Left = 5
    Top = 5
    Width = 463
    Height = 342
  end
  object Label1: TLabel
    Left = 475
    Top = 100
    Width = 111
    Height = 51
    AutoSize = False
    Caption = 'Try combinations of colors to get diferent shades'
    WordWrap = True
  end
  object BitBtn1: TBitBtn
    Left = 475
    Top = 5
    Width = 111
    Height = 25
    Caption = 'Color Region'
    TabOrder = 0
    OnClick = BitBtn1Click
  end
  object chRed: TCheckBox
    Left = 480
    Top = 35
    Width = 97
    Height = 17
    Caption = 'chRed'
    Checked = True
    State = cbChecked
    TabOrder = 1
  end
  object chGreen: TCheckBox
    Left = 480
    Top = 55
    Width = 97
    Height = 17
    Caption = 'chGreen'
    TabOrder = 2
  end
  object chBlue: TCheckBox
    Left = 480
    Top = 75
    Width = 97
    Height = 17
    Caption = 'chBlue'
    TabOrder = 3
  end
end
0

Featured Post

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!

Question has a verified solution.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Suggested Courses

604 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