各位高手:   我这里有几个常见图形图像编辑的编程问题请教大家, 请用c++builder(delphi亦可)
   1. 在画布上画条直线(这个容易)并能把它拉成曲线, 如何编程 ?
   2. 鼠标能拖动已经画好的直线或曲线等, 如何编程 ?
   3. 在画布上绘制文字的问题, 鼠标在画布上任意位置点一下并拉出一个矩形, 在
      矩形中任意输入文字, 可换行, 选定其中某些文字并能改变字体, 绘制出的
      文字能用鼠标任意移动, 并且文字区域的背景仍是原画布的样子, 这些如何编程 ?
   4 .在画布上编辑图形时的redo与undo操作如何编程 ?       截图并编辑软件snagit就有上述图形编辑功能(大家可下载用用), 其他
   许许多多图形编辑软件也都有上述功能. 以上几个编程问题请用c++builder实现 
   (delphi亦可), 并给出具体代码, 或提供针对性的c++builder或delphi资料.
   谢谢 !!     

解决方案 »

  1.   

    1.用B样条
    2.要么重画,要么擦除原来的图形   
    3.用memo组建实现
    4.自己定义存储画图的数据结构,然后可考虑用栈来实现redo与undo
      

  2.   

    我说的是具体如何编程, c++builder或delphi !!!
    能否介绍针对性的资料 ???
      

  3.   

    http://www.codesky.net/showhtml/4357.htm
      

  4.   

    借助动态生成的TImage和TEdit即可实现。
      

  5.   

    能否对我上述提出的 1.3.4 三个问题各提供一个针对性例子 ?? c++builder方面的(delphi亦可)
      

  6.   

    各位高手:
      
      许多图形编辑软件都有这样的功能: 鼠标在原有图形上拉出一个矩形虚线方框, 立即
    弹出文字输入对话框, 在对话框输入文字确定后, 相同的文字会输入到矩形虚线方框内,
    矩形虚线方框连同文字可用鼠标移动或转动, 矩形虚线方框并无背景. 这些如何编程 ??
    动态建立 TMemo ?? 好象可以, 但 TMemo 背景不能为白色, 需要透明, 另外TMemo需要
    动态转动 . 这些能实现吗 ?? 这个思路行吗 ??   一般具有这样功能的软件是如何编程的 ??
      请教正确的编程方法, 最好提供例子(c++builder或delphi方面的).
      

  7.   

    上面说了一会,还是从我给其他帖的例子,转贴过来,可供楼主第一条参考:
        按一下按钮,可以用鼠标在PaintBox1上选点并拖曳,我这设计是起始点和结束点重合才选点完毕.然后自动画闭合曲线,再次按按钮,闭合线消失,又可选点...
        如果你要背景图,可在PaintBox1->OnPaint开始时画上去,很简单的.
        注意,我设了一个20大小的Point数组,没作超过检查.#ifndef Unit1H
    #define Unit1H//---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <ExtCtrls.hpp>
    #include <algorithm>
    using std::min;
    using std::max;
    #include <gdiplus.h>
    using namespace Gdiplus;
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published: // IDE-managed Components
        TPaintBox *PaintBox1;
        TButton *Button1;
        void __fastcall PaintBox1MouseDown(TObject *Sender,
              TMouseButton Button, TShiftState Shift, int X, int Y);
        void __fastcall PaintBox1MouseMove(TObject *Sender, TShiftState Shift,
              int X, int Y);
        void __fastcall Button1Click(TObject *Sender);
        void __fastcall PaintBox1Paint(TObject *Sender);
       
    private: // User declarations
        Gdiplus::GdiplusStartupInput gdiplusStartupInput;
        ULONG gdiplusToken;
        Gdiplus::Point points[20];
        int pointCount;
        Gdiplus::Point MouseOrg, NextPoint;
        bool Drawing;
        bool Beging;
        void __fastcall DrawLine(TPenMode mode);
        bool __fastcall IsEquals();
    public: // User declarations
        __fastcall TForm1(TComponent* Owner);
        __fastcall ~TForm1(void);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif#include <vcl.h>
    #pragma hdrstop#include "Unit1.h"//---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
        GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
        pointCount = 0;
    }
    //---------------------------------------------------------------------------
    __fastcall TForm1::~TForm1(void)
    {
        GdiplusShutdown( gdiplusToken );
    }void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y)
    {
        if(Button != mbLeft || !Beging) return;
        if(!Drawing)
        {
            MouseOrg = Gdiplus::Point(X, Y);
            points[pointCount ++] = MouseOrg;
            NextPoint = MouseOrg;
            Drawing = true;
        }
        else
        {
            DrawLine(pmCopy);
            MouseOrg = NextPoint;
            points[pointCount] = NextPoint;
            if(IsEquals())
            {
                NextPoint = points[0];
                Drawing = false;
                Beging = false;
                PaintBox1->Invalidate();
            }
            else
               pointCount ++;
        }
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender,
          TShiftState Shift, int X, int Y)
    {
        if(Drawing)
        {
            DrawLine(pmNotXor);
            NextPoint = Gdiplus::Point(X, Y);
            DrawLine(pmNotXor);
        }
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        Beging = true;
        pointCount = 0;
        PaintBox1->Invalidate();
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::DrawLine(TPenMode mode)
    {
        PaintBox1->Canvas->Pen->Mode = mode;
        PaintBox1->Canvas->MoveTo(MouseOrg.X, MouseOrg.Y);
        PaintBox1->Canvas->LineTo(NextPoint.X, NextPoint.Y);
    }
    //---------------------------------------------------------------------------
    bool __fastcall TForm1::IsEquals()
    {
        return (NextPoint.X > points[0].X - 2) && (NextPoint.X < points[0].X + 2) &&
                 (NextPoint.Y > points[0].Y - 2) && (NextPoint.Y < points[0].Y + 2);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
    {
        if(Drawing || pointCount == 0)
            return;
        Gdiplus::Graphics g(PaintBox1->Canvas->Handle);
        g.SetSmoothingMode(SmoothingModeHighQuality); 
        g.DrawClosedCurve(&Pen(Gdiplus::Color::Red, 1), points, pointCount);
    }
      

  8.   

    maozefa(阿发伯) :你好!  现在我请教的是以下问题:
      
      
      许多图形编辑软件都有这样的功能: 鼠标在原有图形上拉出一个矩形虚线方框, 立即
    弹出文字输入对话框, 在对话框输入文字确定后, 相同的文字会输入到矩形虚线方框内,
    矩形虚线方框连同文字可用鼠标移动或转动, 矩形虚线方框并无背景. 这些如何编程 ??
    动态建立 TMemo ?? 好象可以, 但 TMemo 背景不能为白色, 需要透明, 另外TMemo需要
    动态转动 . 这些能实现吗 ?? 这个思路行吗 ??   一般具有这样功能的软件是如何编程的 ??
      请教正确的编程方法, 最好提供例子(c++builder或delphi方面的).
      

  9.   

    我给你赶了个例子,使用的TPaintBox控件,字串的字体,颜色,位置你自己确定,没实现旋转功能,供你参考:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls;type
      TForm1 = class(TForm)
        ImageBox: TPaintBox;
        StartDraw: TButton;
        EndDraw: TButton;
        procedure ImageBoxMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure ImageBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
        procedure ImageBoxMouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure StartDrawClick(Sender: TObject);
        procedure EndDrawClick(Sender: TObject);
        procedure ImageBoxPaint(Sender: TObject);
      private
        { Private declarations }
        Beging: Boolean;
        DrawIng: Boolean;
        Moveing: Boolean;
        MovePoint: TPoint;
        MouseOrg: TPoint;
        NextPoint: TPoint;
        FLabel: TLabel;
        procedure DrawCutRect(Mode: TPenMode);
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}{ TForm1 }procedure TForm1.DrawCutRect(Mode: TPenMode);
    begin
      if Mode = pmCopy then
        ImageBox.Canvas.Pen.Style := psSolid
      else
        ImageBox.Canvas.Pen.Style := psDot;
      ImageBox.Canvas.Pen.Mode := Mode;
      ImageBox.Canvas.Brush.Style := bsClear;
      ImageBox.Canvas.Rectangle(MouseOrg.X, MouseOrg.Y, NextPoint.X, NextPoint.Y);
    end;procedure TForm1.ImageBoxMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      if (Button <> mbLeft) or not Beging then Exit;
      if not Drawing then
      begin
        Drawing := True;
        MouseOrg := Point(X, Y);
        NextPoint := MouseOrg;
      end else if not Moveing then
      begin
        Moveing := True;
        MovePoint := Point(X, Y);
      end;
    end;procedure TForm1.ImageBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if not (ssLeft in Shift) then Exit;
      if Drawing or MoveIng then
        DrawCutRect(pmNotXor);
      if Moveing then
      begin
        Inc(MouseOrg.X, X - MovePoint.X);
        Inc(MouseOrg.Y, Y - MovePoint.Y);
        Inc(NextPoint.X, X - MovePoint.X);
        Inc(NextPoint.Y, Y - MovePoint.Y);
        MovePoint := Point(X, Y);
        if Assigned(FLabel) then
        begin
          FLabel.Left := MouseOrg.X + 1;
          FLabel.Top := MouseOrg.Y + 1;
        end;
      end
      else if Drawing then
        NextPoint := Point(X, Y);
      if Drawing or MoveIng then
        DrawCutRect(pmNotXor);
    end;procedure TForm1.ImageBoxMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      s: string;
    begin
      if Moveing then
        Moveing := False
      else if Drawing then
      begin
        s := InputBox('请输入文字', '', '');
        if s <> '' then
        begin
          FLabel := TLabel.Create(Self);
          FLabel.Caption := s;
          FLabel.Left := MouseOrg.X + 1;
          FLabel.Top := MouseOrg.Y + 1;
          FLabel.Parent := Self;
        end;
      end;
    end;procedure TForm1.StartDrawClick(Sender: TObject);
    begin
      if Assigned(FLabel) then
      begin
        FLabel.Parent := nil;
        FreeAndNil(FLabel);
      end;
      NextPoint := MouseOrg;
      Beging := True;
      ImageBox.Invalidate;
    end;procedure TForm1.EndDrawClick(Sender: TObject);
    begin
      Drawing := False;
      Beging := False;
      ImageBox.Invalidate;
    end;procedure TForm1.ImageBoxPaint(Sender: TObject);
    begin
      if Drawing or MoveIng then
        DrawCutRect(pmNotXor)
      else
        DrawCutRect(pmCopy);
    end;end.
      

  10.   

    强烈鄙视问题解决后不结贴的人!
    强烈鄙视技术问题解决后把贴子转移到非技术区的人!
    鄙视你们!http://community.csdn.net/Expert/topic/5216/5216675.xml?temp=.9262659
      

  11.   

    强烈鄙视问题解决后不结贴的人!---------------------------------------强力支持请提问者尊重答题者的付出。http://community.csdn.net/Expert/topic/5213/5213510.xml?temp=.0577051
      

  12.   

    maozefa(阿发伯): 你好!     抱歉! 这几天有事没看帖子, 先生也太急了! 我绝非不尊重答题者付出的人, 
    现在我认真地看了你的帖子, 尽管与我目标相差很远,  但我还是感谢你!  
    绘制文字的问题, FLabel不行, 因为FLabel字符串长度可能回超过虚框, FLabel只是
    单行, 再说鼠标调整虚框大小后, 虚框内的文字图形也不能自动调整, 旋转不用说了.
    看来你真的是热心人, 虽然问题没有解决, 我把分给你.
     
      

  13.   

    尽管与我目标相差很远,  但我还是感谢你! 绘制文字的问题, FLabel不行, 因为FLabel字符串长度可能回超过虚框, FLabel只是单行, 再说鼠标调整虚框大小后, 虚框内的文字图形也不能自动调整, 旋转不用说了。 
    ---------------------------------------
    你这种求解决问题的办法,根本就是要人家代劳你的工作。如果你确实在开发上有很大的阻力,我劝你暂时放弃吧。把基本功再好好练练。虽然问题没有解决, 我把分给你.
    ------------------------------------------
    呵呵呵呵, 你把你的分看得好金贵啊!
      

  14.   

    maozefa(阿发伯)的功底是多年修炼而成的,他哪个时候可没有任何外来资源的帮助,全靠自己的刻苦钻研,GDI+的pascal库都是自己从C++改写来的。很不简单的。
      

  15.   

    to 楼主:
    抱歉! 这几天有事没看帖子, 先生也太急了! 我绝非不尊重答题者付出的人, 
    现在我认真地看了你的帖子, 尽管与我目标相差很远,  但我还是感谢你!  
    ====================================================================================
    本不想驳斥你的,但看起来,你这个人不诚实厚道,只好说说了。    首先,你的要求主要是“鼠标在原有图形上拉出一个矩形虚线方框, 立即
    弹出文字输入对话框, 在对话框输入文字确定后, 相同的文字会输入到矩形虚线方框内,
    矩形虚线方框连同文字可用鼠标移动或转动”,我基本达到你的要求,至于你说的“矩形虚线方框连同文字可用鼠标移动或转动”,我的理解是“移动或者转动”满足一条就行了,所以我实现了“移动”功能。你要求“另外TMemo需要动态转动”,一来我没用TMemo;二来不明白这个TMemo怎么个转动法,我估计整个CSDN高手都没法真正把Delphi的TMemo转动,即使能让TMemo转动,也会相当麻烦,我不过给你个编程思路例子,没有必要编个完整程序给你吧?你的所谓“与我目标相差很远”不过是最低级的托词而已,不信?要不要我发个帖,叫各位高手们来评评这个贴?
        其次,你说“这几天有事没看帖子, 先生也太急了! 我绝非不尊重答题者付出的人”。你真的有事不能上网看帖吗?我最后一个回复是12月5日,你在12月7日发另一帖《关于图形编辑软件undo与redo的编程实现(用c++builder或delphi如何编程 ??)(happymanfreeman1)》,并多次现身在该帖中,你敢说你没看此帖?既然看了此帖,为何不见你说要求如何如何?昨天老冯谴责你,你才说什么回复“与我目标相差很远”,由此可见你这人多不诚实厚道!
        其三,你说“绘制文字的问题, FLabel不行, 因为FLabel字符串长度可能回超过虚框, FLabel只是单行”,你在前面的要求中说过要多行显示吗?又是谁告诉你Flabel(TLabel类型)只是单行显示?
        总之,你这人有点不那个...,你以为所有人回复贴都仅仅是为了你那点“分”,给分制度不过是为了鼓励回帖,造成一种竞争气氛而已,真正高品质的人决不会因你分多少而不回帖的,如目前在D版比较活跃的老冯、伴水等人,包括我,不知回了多少无分贴或者无效分贴。下面是我近几天回的几条无分贴或者无效分贴:http://community.csdn.net/Expert/topic/5220/5220054.xml?temp=.2786371
    http://community.csdn.net/Expert/topic/5234/5234451.xml?temp=.9009516
    http://community.csdn.net/Expert/topic/5234/5234434.xml?temp=.884411