Guten morgen Gemeinde!
Ein Neuer Tag, ein neues problem
Ich versuche aus einem Bitmap eine Durchschnittsfarbe zu ermitteln.
Bei dummzeuch wurde ich zwar fündig was mir bereits sehr half es zu beschleunigen, aber seine letzte Optimierung bekomme ich einfach nicht hin.
Hier ist das was ich aus seinem guten Beispiel #2 gemacht habe, es funktioniert, aber doch recht langsam:
Delphi-Quellcode:
function TfrmMain.GetAvgBmpColor: TColor;
type
TRgbTriple =
packed record
// do not change the order of the fields, do not add any fields
Blue: Byte;
Green: Byte;
Red: Byte;
end;
TRgbTripleArray =
packed array[0..MaxInt
div SizeOf(TRgbTriple) - 1]
of TRgbTriple;
PRgbTripleArray = ^TRgbTripleArray;
var
x, y: Integer;
r, g, b: Integer;
Pixel: TRgbTriple;
Bmp: TBitmap;
Filename:
string;
fs: TFileStream;
wic: TWICImage;
img: TImage;
begin
Filename := '
X:\Pfad\Bildname.ext';
if not FileExists(Filename)
then
Exit;
bmp := TBitmap.Create;
wic := TWICImage.Create;
img := TImage.Create(Self);
fs := TFileStream.Create(Filename, fmOpenRead);
try
bmp.PixelFormat := pf24bit;
fs.Position := 0;
wic.LoadFromStream(fs);
Img.Picture.Assign(wic);
bmp.Width := Img.Picture.Width;
bmp.Height := Img.Picture.Height;
bmp.Canvas.Draw(0, 0, Img.Picture.Graphic);
r := 0; g := 0; b := 0;
Assert(bmp.PixelFormat = pf24bit);
for y := 0
to Pred(bmp.Height)
do
begin
for x := 0
to Pred(bmp.Width)
do
begin
Pixel := PRgbTripleArray(bmp.Scanline[y])^[x];
r := r + Pixel.Red;
g := g + Pixel.Green;
b := b + Pixel.Blue;
end;
end;
r := r
div (bmp.Width * bmp.Height);
g := g
div (bmp.Width * bmp.Height);
b := b
div (bmp.Width * bmp.Height);
finally
Result :=
RGB(r, g, b);
bmp.Free;
fs.Free;
wic.Free;
img.Free;
end;
end;
Sorry für meine schludrige code gestaltung, ist erst alpha phase.
Weiß jemand wie man das eventuell mit diesem Code #3 hinbekommt?
Delphi-Quellcode:
// if you are using Delphi 2007 or older you need to correct the NativeInt declaration from 8 bytes to 4 bytes:
{$IF SizeOf(Pointer) = 4}
type
NativeInt = Integer;
{$IFEND}
function AddToPtr(const _Ptr: Pointer; _Offset: NativeInt): Pointer; inline;
begin
Result := Pointer(NativeInt(_Ptr) + _Offset);
end;
function PtrDiff(const _Ptr1, _Ptr2: Pointer): NativeInt; inline;
begin
Result := NativeInt(_Ptr1) - NativeInt(_Ptr2);
end;
var
BytesPerPixel: NativeInt;
InScanLine0: Pointer;
InBytesPerLine: NativeInt;
OutScanLine0: Pointer;
InBytesPerLine: NativeInt;
InPixel: PRgbTriple;
OutPixel: PRgbTriple;
// ...
BytesPerPixel := SizeOf(Pixel)
InScanLine0 := InBmp.ScanLine[0];
InBytesPerLine := NativeInt(_InBmp.ScanLine[1]) - NativeInt(InScanLine0);
OutScanLine0 := _OutputBmp.ScanLine[0];
OutBytesPerLine := NativeInt(_OutBmp.ScanLine[1]) - NativeInt(OutScanLine0);
OutPixel := OutScanLine0;
for y := 0 to Height - 1 do begin
for x := 0 to Width - 1 do begin
InPixel := AddToPtr(InScanLine0, InBytesPerLine * y + x * BytesPerPixel);
Pixel := InPixel^;
doSomething(Pixel);
OutPixel := AddToPtr(OutScanLine0, OutBytesPerLine * y + x * BytesPerPixel);
OutPixel^ := Pixel;
end;
end;
Ich bekomme immer den Fehler das "Pixel" nicht mit "InPixel^" kompatibel ist und weiß gerade nicht weiter.