C++ Builder FMX如何在内存中拉伸Bitmap并保存至数据库?
在C++ Builder FireMonkey中实现内存中Bitmap的拉伸并保存
FireMonkey里确实没有VCL中StretchDraw那样直接的方法,但可以通过手动创建目标尺寸的Bitmap,再用Canvas的DrawBitmap方法完成拉伸绘制,最终得到可保存的拉伸后图像。具体实现步骤如下:
核心实现代码
假设你已有原Bitmap对象SourceBmp,以及要匹配尺寸的TImage* Image1,以下是生成拉伸后Bitmap并存入数据库Blob的示例:
// 创建与TImage尺寸一致的目标Bitmap TBitmap* ResizedBmp = new TBitmap(); ResizedBmp->SetSize(Image1->Width, Image1->Height); // 开始绘制拉伸图像 ResizedBmp->Canvas->BeginScene(); try { // 源矩形:原Bitmap的完整区域 TRectF SourceRect = TRectF(0, 0, SourceBmp->Width, SourceBmp->Height); // 目标矩形:新Bitmap的完整区域(匹配TImage尺寸) TRectF DestRect = TRectF(0, 0, ResizedBmp->Width, ResizedBmp->Height); // DrawBitmap实现拉伸绘制,最后一个参数设为false表示不强制保持比例 ResizedBmp->Canvas->DrawBitmap(SourceBmp, SourceRect, DestRect, 1.0f, false); } __finally { ResizedBmp->Canvas->EndScene(); } // 将拉伸后的Bitmap存入数据库Blob字段(以FireDAC为例) if (YourQuery->FieldByName("ImageBlob")->DataType == ftBlob) { TBlobField* BlobField = static_cast<TBlobField*>(YourQuery->FieldByName("ImageBlob")); TMemoryStream* Stream = new TMemoryStream(); try { ResizedBmp->SaveToStream(Stream); Stream->Position = 0; BlobField->LoadFromStream(Stream); } __finally { delete Stream; } } // 释放资源,避免内存泄漏 delete ResizedBmp;
关键说明
- DrawBitmap的作用:该方法通过指定不同的源矩形和目标矩形尺寸,自动完成图像的拉伸/缩放绘制,替代VCL的
StretchDraw功能。 - BeginScene/EndScene:FireMonkey的Canvas必须在这两个方法的包裹下执行绘制操作,否则绘制不会生效。
- 保持比例的可选处理:如果需要避免图像拉伸变形,可以根据源图和目标尺寸的比例计算目标矩形,比如:
此时float Scale = Min(ResizedBmp->Width / SourceBmp->Width, ResizedBmp->Height / SourceBmp->Height); float DrawWidth = SourceBmp->Width * Scale; float DrawHeight = SourceBmp->Height * Scale; TRectF DestRect = TRectF( (ResizedBmp->Width - DrawWidth)/2, (ResizedBmp->Height - DrawHeight)/2, (ResizedBmp->Width + DrawWidth)/2, (ResizedBmp->Height + DrawHeight)/2 );DrawBitmap的最后一个参数设为true即可保持比例居中绘制。 - 尺寸获取注意:如果TImage是自适应布局(如
Align = alClient),要确保获取的Width和Height是控件实际显示的尺寸,而非设计时的固定值。
内容的提问来源于stack exchange,提问作者Drewski7280
相关产品推荐
相关产品推荐

