2015-04-08 19:13:43 +02:00
|
|
|
(*
|
|
|
|
****************************************************************
|
|
|
|
Delphi-OpenCV Demo
|
|
|
|
Copyright (C) 2013 Project Delphi-OpenCV
|
|
|
|
****************************************************************
|
|
|
|
Contributor:
|
|
|
|
Laentir Valetov
|
|
|
|
email:laex@bk.ru
|
|
|
|
****************************************************************
|
|
|
|
You may retrieve the latest version of this file at the GitHub,
|
|
|
|
located at git://github.com/Laex/Delphi-OpenCV.git
|
|
|
|
****************************************************************
|
|
|
|
The contents of this file are used with permission, subject to
|
|
|
|
the Mozilla Public License Version 1.1 (the "License"); you may
|
|
|
|
not use this file except in compliance with the License. You may
|
|
|
|
obtain a copy of the License at
|
|
|
|
http://www.mozilla.org/MPL/MPL-1_1Final.html
|
|
|
|
|
|
|
|
Software distributed under the License is distributed on an
|
|
|
|
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
implied. See the License for the specific language governing
|
|
|
|
rights and limitations under the License.
|
|
|
|
****************************************************************
|
|
|
|
*)
|
|
|
|
|
2014-08-06 00:36:22 +02:00
|
|
|
unit ocv.comp.ViewFMX;
|
|
|
|
|
|
|
|
{$I OpenCV.inc}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
2014-08-26 09:17:39 +02:00
|
|
|
uses
|
2014-08-06 00:36:22 +02:00
|
|
|
System.Classes,
|
|
|
|
System.Types,
|
2014-08-26 09:17:39 +02:00
|
|
|
FMX.Types,
|
2014-09-29 09:12:47 +02:00
|
|
|
{$IFDEF DELPHIXE6_UP} // Delphi XE6 and above
|
2014-08-06 00:36:22 +02:00
|
|
|
FMX.Graphics,
|
2014-09-19 13:35:15 +02:00
|
|
|
{$ELSE}
|
2014-08-26 09:17:39 +02:00
|
|
|
FMX.PixelFormats,
|
2014-09-19 13:35:15 +02:00
|
|
|
{$ENDIF}
|
2015-04-08 19:13:43 +02:00
|
|
|
FMX.Controls, ocv.comp.Types;
|
2014-08-06 00:36:22 +02:00
|
|
|
|
2014-10-05 00:51:42 +02:00
|
|
|
{$IFNDEF DELPHIXE5_UP}
|
2015-04-08 19:13:43 +02:00
|
|
|
|
2014-10-05 00:51:42 +02:00
|
|
|
// Delphi XE5 and below
|
2014-08-26 09:17:39 +02:00
|
|
|
const
|
2014-10-05 00:51:42 +02:00
|
|
|
PixelFormatBytes: array [TPixelFormat] of Integer = ( { pfUnknown } 0, { pfA16B16G16R16 } 8, { pfA2R10G10B10 } 4,
|
|
|
|
{ pfA2B10G10R10 } 4,
|
2014-09-19 13:35:15 +02:00
|
|
|
{ pfA8R8G8B8 } 4,
|
2014-10-05 00:51:42 +02:00
|
|
|
{ pfX8R8G8B8 } 4, { pfA8B8G8R8 } 4, { pfX8B8G8R8 } 4, { pfR5G6B5 } 2, { pfA4R4G4B4 } 2, { pfA1R5G5B5 } 2,
|
|
|
|
{ pfX1R5G5B5 } 2,
|
2014-09-19 13:35:15 +02:00
|
|
|
{ pfG16R16 } 4,
|
2014-10-05 00:51:42 +02:00
|
|
|
{ pfA8L8 } 2, { pfA4L4 } 1, { pfL16 } 2, { pfL8 } 1, { pfR16F } 2, { pfG16R16F } 4, { pfA16B16G16R16F } 8,
|
|
|
|
{ pfR32F } 4,
|
2014-09-19 13:35:15 +02:00
|
|
|
{ pfG32R32F } 8, { pfA32B32G32R32F } 16,
|
2014-10-05 00:51:42 +02:00
|
|
|
{ pfA8 } 1, { pfV8U8 } 2, { pfL6V5U5 } 2, { pfX8L8V8U8 } 4, { pfQ8W8V8U8 } 4, { pfV16U16 } 4, { pfA2W10V10U10 } 4,
|
|
|
|
{ pfU8Y8_V8Y8 } 4,
|
2014-09-19 13:35:15 +02:00
|
|
|
{ pfR8G8_B8G8 } 4, { pfY8U8_Y8V8 } 4,
|
2014-10-05 00:51:42 +02:00
|
|
|
{ pfG8R8_G8B8 } 4, { pfQ16W16V16U16 } 8, { pfCxV8U8 } 2, { pfDXT1 } 8, { pfDXT2 } 16, { pfDXT3 } 16, { pfDXT4 } 16,
|
|
|
|
{ pfDXT5 } 16,
|
2014-09-19 13:35:15 +02:00
|
|
|
{ pfA32B32G32R32 } 16, { pfB10G11R11F } 4);
|
2014-08-26 09:17:39 +02:00
|
|
|
{$ENDIF}
|
|
|
|
|
|
|
|
type
|
2014-09-29 09:12:47 +02:00
|
|
|
{$IFNDEF DELPHIXE5_UP} // Delphi XE5 and below
|
2014-08-26 09:17:39 +02:00
|
|
|
TBitmapHack = class helper for TBitmap
|
|
|
|
public
|
|
|
|
procedure SetPixelFormat(Value: TPixelFormat);
|
|
|
|
end;
|
2014-09-19 13:35:15 +02:00
|
|
|
{$ENDIF}
|
|
|
|
|
2014-08-06 00:36:22 +02:00
|
|
|
TocvViewFMX = class(TControl, IocvDataReceiver)
|
|
|
|
private
|
|
|
|
FStretch: Boolean;
|
|
|
|
FocvVideoSource: IocvDataSource;
|
|
|
|
FCenter: Boolean;
|
|
|
|
FProportional: Boolean;
|
|
|
|
FImage: IocvImage;
|
|
|
|
FOnAfterPaint: TOnOcvAfterViewPaint;
|
|
|
|
FOnBeforePaint: TOnOcvNotify;
|
|
|
|
procedure SetOpenCVVideoSource(const Value: IocvDataSource);
|
|
|
|
function isSourceEnabled: Boolean;
|
|
|
|
function PaintRect: TRectF;
|
|
|
|
protected
|
|
|
|
BackBuffer: TBitmap;
|
|
|
|
procedure Paint; override;
|
|
|
|
procedure TakeImage(const IplImage: IocvImage);
|
|
|
|
procedure SetVideoSource(const Value: TObject);
|
|
|
|
public
|
|
|
|
constructor Create(AOwner: TComponent); override;
|
|
|
|
destructor Destroy; override;
|
|
|
|
procedure DrawImage(const IplImage: IocvImage);
|
|
|
|
published
|
|
|
|
property VideoSource: IocvDataSource Read FocvVideoSource write SetOpenCVVideoSource;
|
|
|
|
property Proportional: Boolean read FProportional write FProportional default false;
|
|
|
|
property Stretch: Boolean read FStretch write FStretch default True;
|
|
|
|
property Center: Boolean read FCenter write FCenter default false;
|
|
|
|
property Left;
|
|
|
|
property Top;
|
2014-10-05 00:51:42 +02:00
|
|
|
property Width Stored True;
|
|
|
|
property Height Stored True;
|
2014-08-06 00:36:22 +02:00
|
|
|
property Align;
|
|
|
|
property OnAfterPaint: TOnOcvAfterViewPaint read FOnAfterPaint write FOnAfterPaint;
|
|
|
|
property OnBeforePaint: TOnOcvNotify read FOnBeforePaint write FOnBeforePaint;
|
|
|
|
property OnEnter;
|
|
|
|
property OnExit;
|
|
|
|
property OnKeyDown;
|
|
|
|
property OnKeyUp;
|
|
|
|
property OnMouseDown;
|
|
|
|
property OnMouseUp;
|
|
|
|
property OnMouseMove;
|
|
|
|
property OnMouseEnter;
|
|
|
|
property OnMouseLeave;
|
|
|
|
property OnMouseWheel;
|
|
|
|
property HitTest;
|
|
|
|
property PopupMenu;
|
|
|
|
property TabOrder;
|
|
|
|
property Visible;
|
2014-09-19 13:35:15 +02:00
|
|
|
{$IF CompilerVersion<21.0}
|
2014-08-06 00:36:22 +02:00
|
|
|
property DesignVisible;
|
2014-09-19 13:35:15 +02:00
|
|
|
{$ENDIF}
|
2014-08-06 00:36:22 +02:00
|
|
|
property Opacity;
|
|
|
|
property Margins;
|
|
|
|
property Padding;
|
|
|
|
property Position;
|
|
|
|
end;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
2014-08-26 09:17:39 +02:00
|
|
|
uses
|
2015-08-26 19:35:51 +02:00
|
|
|
System.UITypes,
|
|
|
|
ocv.fmxutils;
|
2014-08-26 09:17:39 +02:00
|
|
|
|
2014-10-05 00:51:42 +02:00
|
|
|
{$IFNDEF DELPHIXE5_UP}
|
2015-04-08 19:13:43 +02:00
|
|
|
|
2014-10-05 00:51:42 +02:00
|
|
|
// Delphi XE5 and below
|
2014-08-26 09:17:39 +02:00
|
|
|
procedure TBitmapHack.SetPixelFormat(Value: TPixelFormat);
|
|
|
|
begin
|
|
|
|
Self.FPixelFormat := Value;
|
|
|
|
end;
|
|
|
|
{$ENDIF}
|
2014-08-06 00:36:22 +02:00
|
|
|
{ TocvVewFMX }
|
|
|
|
|
|
|
|
constructor TocvViewFMX.Create(AOwner: TComponent);
|
|
|
|
begin
|
|
|
|
inherited;
|
2014-09-19 13:35:15 +02:00
|
|
|
|
2014-09-29 10:36:06 +02:00
|
|
|
{$IFDEF DELPHIXE6_UP} // Delphi XE6 and above
|
2014-08-06 00:36:22 +02:00
|
|
|
BackBuffer := TBitmap.Create;
|
2014-09-29 10:36:06 +02:00
|
|
|
{$ENDIF}
|
|
|
|
{$IFDEF DELPHIXE6} // Delphi XE6
|
2014-08-06 00:36:22 +02:00
|
|
|
BackBuffer.PixelFormat := TPixelFormat.RGB;
|
2014-09-29 10:55:12 +02:00
|
|
|
{$ENDIF}
|
|
|
|
{$IFNDEF DELPHIXE6_UP} // Delphi XE5 and below
|
2014-08-26 09:17:39 +02:00
|
|
|
BackBuffer := TBitmap.Create(0, 0);
|
|
|
|
BackBuffer.SetPixelFormat(TPixelFormat.pfX8R8G8B8);
|
2014-09-19 13:35:15 +02:00
|
|
|
{$ENDIF}
|
2014-08-06 00:36:22 +02:00
|
|
|
Stretch := True;
|
2014-09-19 13:35:15 +02:00
|
|
|
Proportional := false;
|
|
|
|
Center := false;
|
2014-08-06 00:36:22 +02:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TocvViewFMX.Destroy;
|
|
|
|
begin
|
|
|
|
BackBuffer.Free;
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TocvViewFMX.DrawImage(const IplImage: IocvImage);
|
|
|
|
begin
|
|
|
|
FImage := IplImage;
|
|
|
|
Repaint;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TocvViewFMX.isSourceEnabled: Boolean;
|
|
|
|
begin
|
|
|
|
Result := (Assigned(VideoSource) and (VideoSource.Enabled)) or Assigned(FImage);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TocvViewFMX.Paint;
|
2015-09-19 21:49:45 +02:00
|
|
|
//var
|
|
|
|
// M: TBitmapData;
|
|
|
|
// i: Integer;
|
|
|
|
// SrcData, DestData: pByte;
|
|
|
|
// nC: Integer;
|
2014-08-06 00:36:22 +02:00
|
|
|
begin
|
|
|
|
if (csDesigning in ComponentState) then
|
|
|
|
begin
|
|
|
|
Canvas.Stroke.Thickness := 1;
|
|
|
|
Canvas.Stroke.Kind := TBrushKind.bkSolid;
|
|
|
|
Canvas.Stroke.Color := TAlphaColorRec.Black;
|
|
|
|
Canvas.DrawRect(RectF(0, 0, Width, Height), 0, 0, AllCorners, 1);
|
|
|
|
end
|
|
|
|
else if (not isSourceEnabled) or (not Assigned(FImage)) then
|
|
|
|
inherited
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
if Assigned(OnBeforePaint) then
|
|
|
|
OnBeforePaint(Self, FImage);
|
|
|
|
|
2015-08-26 19:35:51 +02:00
|
|
|
IPLImageToFMXBitmap(FImage.IpImage, BackBuffer);
|
2014-08-06 00:36:22 +02:00
|
|
|
Canvas.DrawBitmap(BackBuffer, RectF(0, 0, BackBuffer.Width, BackBuffer.Height), PaintRect, 1, True);
|
|
|
|
|
|
|
|
if Assigned(OnAfterPaint) then
|
|
|
|
OnAfterPaint(Self, FImage);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TocvViewFMX.PaintRect: TRectF;
|
|
|
|
var
|
2014-09-19 13:35:15 +02:00
|
|
|
ViewWidth, ViewHeight, CliWidth, CliHeight: Integer;
|
2014-08-06 00:36:22 +02:00
|
|
|
AspectRatio: Double;
|
|
|
|
begin
|
|
|
|
ViewWidth := FImage.IpImage^.Width;
|
|
|
|
ViewHeight := FImage.IpImage^.Height;
|
|
|
|
CliWidth := Trunc(Width);
|
|
|
|
CliHeight := Trunc(Height);
|
|
|
|
if (Proportional and ((ViewWidth > CliWidth) or (ViewHeight > CliHeight))) or Stretch then
|
|
|
|
begin
|
|
|
|
if Proportional and (ViewWidth > 0) and (ViewHeight > 0) then
|
|
|
|
begin
|
|
|
|
AspectRatio := ViewWidth / ViewHeight;
|
|
|
|
if ViewWidth > ViewHeight then
|
|
|
|
begin
|
|
|
|
ViewWidth := CliWidth;
|
|
|
|
ViewHeight := Trunc(CliWidth / AspectRatio);
|
|
|
|
if ViewHeight > CliHeight then
|
|
|
|
begin
|
|
|
|
ViewHeight := CliHeight;
|
|
|
|
ViewWidth := Trunc(CliHeight * AspectRatio);
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
ViewHeight := CliHeight;
|
|
|
|
ViewWidth := Trunc(CliHeight * AspectRatio);
|
|
|
|
if ViewWidth > CliWidth then
|
|
|
|
begin
|
|
|
|
ViewWidth := CliWidth;
|
|
|
|
ViewHeight := Trunc(CliWidth / AspectRatio);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
ViewWidth := CliWidth;
|
|
|
|
ViewHeight := CliHeight;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
With Result do
|
|
|
|
begin
|
|
|
|
Left := 0;
|
|
|
|
Top := 0;
|
|
|
|
Right := ViewWidth;
|
|
|
|
Bottom := ViewHeight;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if Center then
|
|
|
|
OffsetRect(Result, (CliWidth - ViewWidth) div 2, (CliHeight - ViewHeight) div 2);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TocvViewFMX.SetOpenCVVideoSource(const Value: IocvDataSource);
|
|
|
|
begin
|
|
|
|
if FocvVideoSource <> Value then
|
|
|
|
begin
|
|
|
|
if Assigned(FocvVideoSource) then
|
|
|
|
FocvVideoSource.RemoveReceiver(Self);
|
|
|
|
FocvVideoSource := Value;
|
|
|
|
if Assigned(FocvVideoSource) then
|
|
|
|
FocvVideoSource.AddReceiver(Self);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TocvViewFMX.SetVideoSource(const Value: TObject);
|
|
|
|
begin
|
|
|
|
VideoSource := Value as TocvDataSource;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TocvViewFMX.TakeImage(const IplImage: IocvImage);
|
|
|
|
begin
|
|
|
|
if not(csDestroying in ComponentState) then
|
|
|
|
DrawImage(IplImage);
|
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|