Files
AC_Pro/ImgCopperFormUnit.cpp
2026-06-13 00:05:19 +08:00

563 lines
16 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "ImgCopperFormUnit.h"
#include "GlobalUnit.h"
#include <System.IOUtils.hpp>
//---------------------------------------------------------------------------
static const COLORREF CLR_LINE_D = RGB( 18, 19, 21 ),
CLR_LINE_L = RGB( 140, 141, 145 );
#define TOP_LEFT 0
#define TOP_RIGHT 1
#define BOTTOM_LEFT 2
#define BOTTOM_RIGHT 3
#define TOP 4
#define BOTTOM 5
#define LEFT 6
#define RIGHT 7
#define CENTER 8
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PNGButton"
#pragma link "GeneralDialogPanel"
#pragma link "TextButton"
#pragma resource "*.dfm"
TImgCopperForm *ImgCopperForm;
//---------------------------------------------------------------------------
__fastcall TImgCopperForm::TImgCopperForm(TComponent* Owner, TRect rtCopper, TPicture *pPicSrc)
: TForm(Owner)
{
m_rtCopper = rtCopper;
m_pPicSrc = new TPicture();
if(pPicSrc && pPicSrc->Graphic->Width && pPicSrc->Graphic->Height ) {
m_pPicSrc->Assign(pPicSrc);
}
m_pTBitmapLine = new TBitmap();
m_pTBitmapLine->SetSize(4, 4);
m_pTBitmapLine->Canvas->Brush->Style = bsClear;
for( int indexY=0; indexY<4; indexY++ )
{
bool bLine = (indexY%2==0)?true:false;
for( int indexX=0; indexX<4; indexX++ )
{
bool bEven = (indexX%2==0)?true:false;
if(bLine) bEven = !bEven;
m_pTBitmapLine->Canvas->Pixels[indexX][indexY] =
(bEven==true)?CLR_LINE_D:CLR_LINE_L;
}
}
// -----
m_bPicDown = false;
m_nResize = 1;
DragAcceptFiles(this->Handle, true);
m_pTransSkinScollBar = new TTransSkinScollBar(m_pPanelBKG);
m_pTransSkinScollBar->Parent = m_pPanelBKG;
m_pTransSkinScollBar->SetBounds(0, 0, 14, 100);
m_pTransSkinScollBar->Vertial = false;
m_pTransSkinScollBar->ThumbWidth = 12;
m_pTransSkinScollBar->OnChangePos = SizeChange;
m_pTransSkinScollBar->BringToFront();
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::FormCreate(TObject *Sender)
{
//绘制圆角窗体
FormResize(NULL);
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::FormClose(TObject *Sender, TCloseAction &Action)
{
SAFE_DELETE(m_pTBitmapLine)
SAFE_DELETE(m_pPicSrc)
SAFE_DELETE(m_pTransSkinScollBar)
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::FormResize(TObject *Sender)
{
m_pPanelBKG->Width = Width;
m_pPanelBKG->Height = Height;
m_pPanelBKG->Left = 0;
m_pPanelBKG->Top = 0;
// -----
TRect rtBKG = TRect(1, 26, Width-1, 26+(Height-68));
m_rtBKG = rtBKG;
m_pPaintBoxSrc->Left = 1;
m_pPaintBoxSrc->Top = rtBKG.Top;
m_pPaintBoxSrc->Width = Width-2;
m_pPaintBoxSrc->Height = rtBKG.Height();
m_rtCopperEdge.Left = rtBKG.Left+(rtBKG.Width()-m_rtCopper.Width())/2-4;
m_rtCopperEdge.Top = rtBKG.Top+(rtBKG.Height()-m_rtCopper.Height())/2-4;
m_rtCopperEdge.Right = m_rtCopperEdge.Left+m_rtCopper.Width()+8;
m_rtCopperEdge.Bottom = m_rtCopperEdge.Top+m_rtCopper.Height()+8;
m_pTransSkinScollBar->Width = Width/3;
m_pTransSkinScollBar->Left
= m_pPaintBoxSrc->Left+(m_pPaintBoxSrc->Width-m_pTransSkinScollBar->Width)/2;
m_pTransSkinScollBar->Top
= m_pPaintBoxSrc->Top+m_pPaintBoxSrc->Height -
m_pTransSkinScollBar->Height-8;
HRGN hRgnSize =
CreateRoundRectRgn( 0, 0,
m_pTransSkinScollBar->Width+1,
m_pTransSkinScollBar->Height+1,
3, 3 );
SetWindowRgn( m_pTransSkinScollBar->Handle, hRgnSize, false );
DeleteObject( hRgnSize );
m_pBtnCancel->Left = Width-m_pBtnCancel->Width-10;
m_pBtnCancel->Top = Height-m_pBtnCancel->Height-10;
m_pBtnOk->Left = m_pBtnCancel->Left-m_pBtnOk->Width-10;
m_pBtnOk->Top = m_pBtnCancel->Top;
m_btnChoose->Left = 10;
m_btnChoose->Top =
m_pBtnCancel->Top+(m_pBtnCancel->Height-m_btnChoose->Height)/2;
m_pPanelBKG->Caption = Caption;
SetSrcPicRect();
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::SetCaption(String strCaption)
{
m_pPanelBKG->Caption = strCaption;
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::m_pPaintBoxSrcPaint(TObject *Sender)
{
int nWidth = m_pPaintBoxSrc->Width;
int nHeight = m_pPaintBoxSrc->Height;
// 创建一个与显示设备兼容的内存设备
HDC BufDC = CreateCompatibleDC(m_pPaintBoxSrc->Canvas->Handle);
// 创建一个与显示设备兼容的位图
HBITMAP BufBitmap = CreateCompatibleBitmap(m_pPaintBoxSrc->Canvas->Handle, nWidth, nHeight);
// 将设备与位图关联
SelectObject(BufDC, BufBitmap);
// CreateCompatibleBitmap创建位图后数据初始化为0,而RGB(0,0,0)则表示是黑色
// 这里需要清除其黑色背景,使其变为透明
PerformEraseBackground(this, BufDC);
// 临时的Canvas,用来画图用,但它并不是必须的,可以直接使用GDI函数来画图
TCanvas *CanvasDraw = new TCanvas();
// 关联到内存设备
CanvasDraw->Handle = BufDC;
//--------------------------------------
CanvasDraw->Brush->Color = RGB(52, 56, 63);
CanvasDraw->FillRect(TRect(0, 0, nWidth, nHeight));
CanvasDraw->StretchDraw(m_rtSrc, m_pPicSrc->Graphic);
int iLeft, iTop, iWidth, iHeight;
CanvasDraw->Brush->Bitmap = m_pTBitmapLine;
//left
iLeft = m_rtCopperEdge.Left-m_rtBKG.Left;
iTop = m_rtCopperEdge.Top-m_rtBKG.Top;
iWidth = 4;
iHeight = m_rtCopperEdge.Height();
CanvasDraw->FillRect( TRect(iLeft, iTop, iLeft+iWidth, iTop+iHeight) );
//right
iLeft = m_rtCopperEdge.Left+m_rtCopperEdge.Width()-4-m_rtBKG.Left;
iTop = m_rtCopperEdge.Top-m_rtBKG.Top;
iWidth = 4;
iHeight = m_rtCopperEdge.Height();
CanvasDraw->FillRect( TRect(iLeft, iTop, iLeft+iWidth, iTop+iHeight) );
//top
iLeft = m_rtCopperEdge.Left-m_rtBKG.Left;
iTop = m_rtCopperEdge.Top-m_rtBKG.Top;
iWidth = m_rtCopperEdge.Width();
iHeight = 4;
CanvasDraw->FillRect( TRect(iLeft, iTop, iLeft+iWidth, iTop+iHeight) );
//bottom
iLeft = m_rtCopperEdge.Left-m_rtBKG.Left;
iTop = m_rtCopperEdge.Top+m_rtCopperEdge.Height()-4-m_rtBKG.Top;
iWidth = m_rtCopperEdge.Width();
iHeight = 4;
CanvasDraw->FillRect( TRect(iLeft, iTop, iLeft+iWidth, iTop+iHeight) );
// 一次性将内存图像数据覆盖过去,因为跳过了擦除背景过程,所以避免了闪烁的问题
BitBlt(m_pPaintBoxSrc->Canvas->Handle, 0, 0, nWidth, nHeight,
CanvasDraw->Handle, 0, 0, SRCCOPY);
// 释放资源
DeleteDC(BufDC);
DeleteObject(BufBitmap);
SAFE_DELETE(CanvasDraw)
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::m_pPaintBoxSrcMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
m_bPicDown = true;
m_ptDown = TPoint(X, Y);
m_rtSrcMove = m_rtSrc;
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::m_pPaintBoxSrcMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
if( m_bPicDown ) {
int nLeft, nTop, nWidth, nHeight;
nWidth = m_rtSrcMove.Width();
nHeight = m_rtSrcMove.Height();
nLeft = m_rtSrcMove.Left+X-m_ptDown.X;
nTop = m_rtSrcMove.Top+Y-m_ptDown.Y;
m_rtSrc.Left = nLeft;
m_rtSrc.Top = nTop;
m_rtSrc.Right = m_rtSrc.Left+nWidth;
m_rtSrc.Bottom = m_rtSrc.Top+nHeight;
m_pPaintBoxSrcPaint(NULL);
}
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::m_pPaintBoxSrcMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
m_bPicDown = false;
m_rtSrcMove = m_rtSrc;
m_pTransSkinScollBar->Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::SizeChange(TObject *Sender)
{
int nSize = m_pTransSkinScollBar->SBTop + 1;
if(m_nResize==nSize) return;
m_nResize = nSize;
int nLMove, nTMove, nWMove, nHMove;
nLMove = m_rtSrcMove.Left;
nTMove = m_rtSrcMove.Top;
nWMove = m_rtSrcMove.Width();
nHMove = m_rtSrcMove.Height();
int nLBac, nTBac, nWBac, nHBac;
nLBac = m_rtSrcBac.Left;
nTBac = m_rtSrcBac.Top;
nWBac = m_rtSrcBac.Width();
nHBac = m_rtSrcBac.Height();
//方向
int nStatusLoc;
TPoint ptCenterSrcMove = TPoint(nLMove+nWMove/2, nTMove+nHMove/2);
if( ptCenterSrcMove.X>m_rtSrcBac.Right &&
ptCenterSrcMove.Y<m_rtSrcBac.Top )
{
nStatusLoc = TOP_RIGHT;
}else if( ptCenterSrcMove.X>m_rtSrcBac.Right &&
ptCenterSrcMove.Y>m_rtSrcBac.Bottom )
{
nStatusLoc = BOTTOM_RIGHT;
}else if( ptCenterSrcMove.X<m_rtSrcBac.Left &&
ptCenterSrcMove.Y>m_rtSrcBac.Bottom )
{
nStatusLoc = BOTTOM_LEFT;
}else if( ptCenterSrcMove.X<m_rtSrcBac.Left &&
ptCenterSrcMove.Y<m_rtSrcBac.Top )
{
nStatusLoc = TOP_LEFT;
}else if( ptCenterSrcMove.X>m_rtSrcBac.Right &&
ptCenterSrcMove.Y>m_rtSrcBac.Top &&
ptCenterSrcMove.Y<m_rtSrcBac.Bottom )
{
nStatusLoc = RIGHT;
}else if( ptCenterSrcMove.X<m_rtSrcBac.Left &&
ptCenterSrcMove.Y>m_rtSrcBac.Top &&
ptCenterSrcMove.Y<m_rtSrcBac.Bottom )
{
nStatusLoc = LEFT;
}else if( ptCenterSrcMove.Y>m_rtSrcBac.Bottom &&
ptCenterSrcMove.X>m_rtSrcBac.Left &&
ptCenterSrcMove.X<m_rtSrcBac.Right )
{
nStatusLoc = BOTTOM;
}else if( ptCenterSrcMove.Y<m_rtSrcBac.Top &&
ptCenterSrcMove.X>m_rtSrcBac.Left &&
ptCenterSrcMove.X<m_rtSrcBac.Right )
{
nStatusLoc = TOP;
}else{
nStatusLoc = CENTER;
}
//得到缩放焦点
TPoint ptFocus;
if( CENTER==nStatusLoc ) {
ptFocus = ptCenterSrcMove;
}else if( TOP_RIGHT==nStatusLoc ) {
ptFocus = TPoint(nLMove+nWMove/4, nTMove+nHMove*3/4);
}else if( BOTTOM_RIGHT==nStatusLoc ) {
ptFocus = TPoint(nLMove+nWMove/4, nTMove+nHMove/4);
}else if( BOTTOM_LEFT==nStatusLoc ) {
ptFocus = TPoint(nLMove+nWMove*3/4, nTMove+nHMove/4);
}else if( TOP_LEFT==nStatusLoc ) {
ptFocus = TPoint(nLMove+nWMove*3/4, nTMove+nHMove*3/4);
}else if( RIGHT==nStatusLoc ) {
ptFocus = TPoint(nLMove+nWMove/4, nTMove+nHMove/2);
}else if( LEFT==nStatusLoc ) {
ptFocus = TPoint(nLMove+nWMove*3/4, nTMove+nHMove/2);
}else if( BOTTOM==nStatusLoc ) {
ptFocus = TPoint(nLMove+nWMove/2, nTMove+nHMove/4);
}else if( TOP==nStatusLoc ) {
ptFocus = TPoint(nLMove+nWMove/2, nTMove+nHMove*3/4);
}
//进行缩放处理
int nLSrc, nTSrc, nWSrc, nHSrc;
nWSrc = nWBac*nSize;
nHSrc = nHBac*nSize;
if( CENTER==nStatusLoc ) {
nLSrc = ptFocus.X - nWSrc/2;
nTSrc = ptFocus.Y - nHSrc/2;
}else if( TOP_RIGHT==nStatusLoc ) {
nLSrc = ptFocus.X - nWSrc/4;
nTSrc = ptFocus.Y - nHSrc*3/4;
}else if( BOTTOM_RIGHT==nStatusLoc ) {
nLSrc = ptFocus.X - nWSrc/4;
nTSrc = ptFocus.Y - nHSrc/4;
}else if( BOTTOM_LEFT==nStatusLoc ) {
nLSrc = ptFocus.X - nWSrc*3/4;
nTSrc = ptFocus.Y - nHSrc/4;
}else if( TOP_LEFT==nStatusLoc ) {
nLSrc = ptFocus.X - nWSrc*3/4;
nTSrc = ptFocus.Y - nHSrc*3/4;
}else if( RIGHT==nStatusLoc ) {
nLSrc = ptFocus.X - nWSrc/4;
nTSrc = ptFocus.Y - nHSrc/2;
}else if( LEFT==nStatusLoc ) {
nLSrc = ptFocus.X - nWSrc*3/4;
nTSrc = ptFocus.Y - nHSrc/2;
}else if( BOTTOM==nStatusLoc ) {
nLSrc = ptFocus.X - nWSrc/2;
nTSrc = ptFocus.Y - nHSrc/4;
}else if( TOP==nStatusLoc ) {
nLSrc = ptFocus.X - nWSrc/2;
nTSrc = ptFocus.Y - nHSrc*3/4;
}
m_rtSrc.Left = nLSrc;
m_rtSrc.Top = nTSrc;
m_rtSrc.Right = m_rtSrc.Left+nWSrc;
m_rtSrc.Bottom = m_rtSrc.Top+nHSrc;
m_pPaintBoxSrcPaint(NULL);
m_pTransSkinScollBar->Refresh();
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::SetSrcPicRect()
{
int nLeft, nTop, nWidth, nHeight;
if( m_pPicSrc ) {
int nWidthLarge = -1;
int nWidthCopper = m_rtCopper.Width();
int nHeightCopper = m_rtCopper.Height();
nWidth = m_pPicSrc->Width;
nHeight = m_pPicSrc->Height;
if( nWidth<m_rtCopper.Width() ) {
nLeft = (nWidthCopper-nWidth)/2;
}else{
nWidthLarge = nWidth;
nLeft = 0;
nWidth = nWidthCopper;
}
if( -1!=nWidthLarge ) {
nHeight = nHeight*nWidth/nWidthLarge;
}
nTop = (nHeightCopper-nHeight)/2;
m_rtSrc.Left = nLeft+(m_rtCopperEdge.Left-m_pPaintBoxSrc->Left)+4;
m_rtSrc.Top = nTop+(m_rtCopperEdge.Top-m_pPaintBoxSrc->Top)+4;
m_rtSrc.Right = m_rtSrc.Left+nWidth;
m_rtSrc.Bottom = m_rtSrc.Top+nHeight;
m_rtSrcBac = m_rtSrc;
m_rtSrcMove = m_rtSrc;
if( -1!=nWidthLarge )
m_pTransSkinScollBar->SBTotal = m_pPicSrc->Width*5/m_rtSrc.Width();
else
m_pTransSkinScollBar->SBTotal = 5;
m_pTransSkinScollBar->SBShow = 2;
m_pTransSkinScollBar->SBTop = 0;
m_nResize = 1;
}
}
//---------------------------------------------------------------------------
bool __fastcall TImgCopperForm::SetSrcPic(String fileName)
{
TMemoryStream *memoryStream = new TMemoryStream();
memoryStream->Position = 0;
memoryStream->LoadFromFile(fileName);
if( !GetPicType(fileName, memoryStream, true) ){
SAFE_DELETE(memoryStream)
return false;
}else {
TPicture *pTPicture = new TPicture();
try{
pTPicture->LoadFromFile(fileName);
}catch(Exception &e){
SAFE_DELETE(pTPicture)
SAFE_DELETE(memoryStream)
return false;
}
if( m_pPicSrc ) {
m_pPicSrc->Assign(pTPicture);
SetSrcPicRect();
m_pPaintBoxSrcPaint(NULL);
m_pTransSkinScollBar->Invalidate();
SAFE_DELETE(pTPicture)
}
}
SAFE_DELETE(memoryStream)
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::WMDRopFiles (TMessage& Msg)
{
wchar_t wcFileName[256];
int iCount = DragQueryFile((HDROP)Msg.WParam, 0xffffffff, wcFileName , 256);
for (int index=0; index<iCount; index++)
{
DragQueryFile((HDROP )Msg.WParam, index, wcFileName , 256);
String fileName = wstr2str(wcFileName).c_str();
if( SetSrcPic(fileName) ) break;
}
DragFinish((HDROP)Msg.WParam);
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::m_btnChooseClick(TObject *Sender)
{
String strPicPath;
// -----
TOpenDialog *pDlg = new TOpenDialog(NULL);
pDlg->Title = "打开图片";
pDlg->Options << ofFileMustExist;
// pDlg->FileName = ExtractFileName(L"");
// pDlg->InitialDir = ExtractFilePath(L"");
pDlg->Filter = "jpg文件 (*.jpg)|*.JPG|png文件 (*.png)|*.PNG|bmp文件 (*.bmp)|*.BMP";
pDlg->DefaultExt = "jpg";
if ( pDlg->Execute(Handle) ) {
strPicPath = pDlg->FileName.c_str();
}
SAFE_DELETE(pDlg);
if( !strPicPath.IsEmpty() ){
SetSrcPic(strPicPath);
}
}
//---------------------------------------------------------------------------
void __fastcall TImgCopperForm::m_pBtnOkClick(TObject *Sender)
{
int iLeft, iTop, iWidth, iHeight;
iLeft = 0;
iTop = 0;
iWidth = m_rtCopper.Width();
iHeight = m_rtCopper.Height();
TBitmap *pTBitmapCopper = new TBitmap();
pTBitmapCopper->SetSize(iWidth, iHeight);
pTBitmapCopper->Canvas->Brush->Color = RGB(0, 0, 0);
pTBitmapCopper->Canvas->FillRect(TRect(iLeft, iTop, iLeft+iWidth, iTop+iHeight));
iWidth = m_rtSrc.Width();
iHeight = m_rtSrc.Height();
m_rtSrc.Left -= m_rtCopperEdge.Left-m_pPaintBoxSrc->Left+4;
m_rtSrc.Top -= m_rtCopperEdge.Top-m_pPaintBoxSrc->Top+4;
m_rtSrc.Right = m_rtSrc.Left+iWidth;
m_rtSrc.Bottom = m_rtSrc.Top+iHeight;
pTBitmapCopper->Canvas->StretchDraw(m_rtSrc, m_pPicSrc->Graphic);
m_strCopperPath = g_strUserPath.c_str();
m_strCopperPath += L"temp\\";
if(!DirectoryExists(m_strCopperPath, false))
ForceDirectories(m_strCopperPath);
m_strCopperPath += L"copper.jpg";
TJPEGImage *pTJPEGImage = new TJPEGImage();
pTJPEGImage->Assign(pTBitmapCopper);
pTJPEGImage->SaveToFile( m_strCopperPath );
SAFE_DELETE(pTJPEGImage);
SAFE_DELETE(pTBitmapCopper);
}
//---------------------------------------------------------------------------