• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 203
  • Last Modified:

Opinions on best way to do this...

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
Palamedes
Asked:
Palamedes
  • 5
  • 4
  • 3
  • +1
1 Solution
 
mokuleCommented:
Use
windows.CreatePolygonRgn
0
 
mokuleCommented:
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
 
mokuleCommented:
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
Industry Leaders: 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!

 
shaneholmesCommented:
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
 
PalamedesAuthor Commented:
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
 
PalamedesAuthor Commented:
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
 
shaneholmesCommented:
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
 
mokuleCommented:
Sorry for some mess.
Yes of course it was cut from bigger application.
0
 
PalamedesAuthor Commented:
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
 
mokuleCommented:
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
 
shaneholmesCommented:
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
 
shaneholmesCommented:
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
 
xxflipCommented:
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

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 5
  • 4
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now