angusj
-
Content Count
132 -
Joined
-
Last visited
-
Days Won
8
Posts posted by angusj
-
-
2 hours ago, DigitalWolF said:Structure viewer is one of the core features of Hextor.
I found it. I thought opening the structures tab with a PE file loaded might show the structure automatically, but I realise now that I have to click on what's on my PC a very tiny toolbar icon that drops a menu to manually load the the structure definition. That's just fine with me (except for the tiny icon 😜).
Anyhow, thanks again for sharing your work.
-
On 8/18/2022 at 3:50 AM, DigitalWolF said:Feedback and feature suggestions are welcome.
My first impression is it looks very promising. Thanks for sharing!
1. Semi-urgent request:
Either automatically or manually resize toolbar icons as they are currently unreadably small on high DPI displays.
Suggest SVG icons as they resize very well.
2. Suggestion:
I see support for viewing image files (which makes sense since they can be embedded as resources),
but I would really like to see viewers for file structures (eg PE File format and zip file structures)
-
3 hours ago, Attila Kovacs said:with TJpegImageHack(jpeg{<-TJPEGImage
It's not pretty, but on occasions it's a useful way around protected properties and methods.
-
2 hours ago, Attila Kovacs said:So you are classify your own library as a short time solution?
No. What I'm saying is if you just need this to solve a short term problem - ie convert 1000s of images as a one off, then a hidden bug is not likely to cause grief. But if this code is going to be used for a very long time, then I'd recommend digging a little deeper and trying to locate the root cause of your memory consumption. (And I really am trying to help, not gang up on you.)
- 1
-
18 minutes ago, Attila Kovacs said:It's always your best guess.
In fairness, I think David asks a valid question. While it's certainly possible this presumed leak is due to a bug in Delphi code, based on probabilities it's much more likely in your code. Even though it's now working (without TJpegImage or whatever), it's likely still there, just not currently causing problems. If a short term fix is all you need then that's great. But it you're counting on this to work in a presumably unattended server long term, it's usually better to invest the time to find out the definitive cause now than have things blow up later when it's far less convenient.
-
2 hours ago, Attila Kovacs said:With your lib, in 8 threads, converting 13GB/5200 jpg's the application takes 500MB-1GBPeak RAM.
With my converter, TPicture.LoadFromFile, DrawTo TBitmap, Resize to another TBitmap, assign to JPEGImage, save: RAM is linear up to 13GB+.
There is no memory leak, something in Windows is holding some working RAM or whatever. I don't care anymore.
Thanks, I'm very pleased to hear that. And I'm now curious as to how the performance compares with your converter?
Also, I could fairly easily modify Delphi's JPEG unit to expose the functions in the JPEG OBJ files and bypass TBitmap entirely but I'm not sure it's worth the effort thought it could improve performance .
-
1 hour ago, Attila Kovacs said:don't know the internals, but that needs TBitmap
Not necessarily. In my Image32 graphics library, I'm using Delphi's JPEG unit without touching TBitmap.Edit: Sorry, the JPEG unit does use TBitmap.
- 1
-
The attached file contains a utility I created some time ago to work around Delphi's IDE that was almost unusable on high DPI screens.
(And I still use it in Delphi 10.4.)
In it you'll see a file called IDEFontSizeFix.pas that does (or at least demonstrates) most of what you're asking.
-
6 minutes ago, xstrider said:But your earlier post promised a stand alone solution ("It requires no specific graphics library to use, just a few extra functions (also included below)") but this doesn't seem to be true.
I wasn't suggesting that you download Image32, just a couple of extra functions. And MakePath was only a shortcut to demonstrate path construction, which of course you'd generate in your own way. And even with FlattenCBezier, I was (I think quite reasonably) expecting that your graphics library could handle this since cubic bezier paths are a very common graphics data structure. Anyhow, I'm sorry I dissapointed you.
-
12 hours ago, xstrider said:Hi Angus, I just discovered your GetSmoothPath() routine. I'm very interested to use it - but I can't make it work.
Hi xstrider.
I've actually modified this function again since posting the link above, but I didn't want to abuse this thread since it's not specifically about my routine.
Anyhow, here's the link to the up to date documentation on this function that's been renamed SmoothToCubicBezier (which I think better describes what the function does).
This can be found in the Img32.Extra unit that part of my Image32 Library on GitHub.
Both MakePath and FlattenCBezier are found in Img32.Vector.
12 hours ago, xstrider said:I also wonder why do you convert an array of Doubles to an array of integers and then assign the result again to an array of doubles?
I'm not sure what you're referring to here. The MakePath function parameter is array of double, and the entire Image32 library uses double coordinate values.
12 hours ago, xstrider said:How should I use the the tGPGraphicsPath.Flatten of GDI+? It doesn't accept a tPathD as an argument.
It appears you're using GDIPlus and I'm not familiar with it. However, while GraphicsPath does accept cubic bezier input (and will flatten these), these beziers appear to be cubic bezier splines, which are very different to cubic bezier arrays. Nevertheless you could copy FlattenCBezier from my library and simply add the flattened path using GraphicsPath's AddPolygon method.
I hope that helps.
ps: Here's a link to a short video that demonstrates this smoothing (together with vectorizing monochrome raster images, and path simplification).
- 1
-
And I still think Idera has the math all wrong. If they sold Delphi Developer at 1/3 the current price, I believe they'd more than triple their sales. As a hobby developer I'd be prepared to spend that instead of using the CE, which I'm currently using.
Edit: At the very least Idera should do some market research and ask CE users what they'd be prepared to spend for the Developer edition. Heaven forbid, they might even attract some new developers instead of just bleeding their current user base.
- 2
- 1
-
-
On 5/23/2022 at 5:18 PM, angusj said:Here's my GetSmoothPath() routine.
I've simplified this and uploaded it here:
- 1
-
2 hours ago, Anders Melander said:It's abandonware
Indeed it is. Although the zip files are still there (DrawObjects and DrawObjectsDemo), I've removed the published links because this code is obsolete (and untouched for more than 10yrs) since Graphics32 has evolved and I've also moved on to other things 😁.
-
Here's my GetSmoothPath() routine. It requires no specific graphics library to use, just a few extra functions (also included below).
This function generates an array of control points that's very easily converted into a flattened cubic bezier path using just about any 2D graphics library.
(nb: The code below has been written with simplicity as the focus rather than performance.)
uses SysUtils, Math; type TPointD = record X, Y: double; end; TPathD = array of TPointD; TArrayOfDouble = array of double; function DistanceSqrd(const pt1, pt2: TPointD): double; begin result := Sqr(pt1.X - pt2.X) + Sqr(pt1.Y - pt2.Y); end; function Distance(const pt1, pt2: TPointD): double; begin Result := Sqrt(DistanceSqrd(pt1, pt2)); end; function OffsetPoint(const pt: TPointD; dx, dy: double): TPointD; begin result.x := pt.x + dx; result.y := pt.y + dy; end; function GetAvgUnitVector(const vec1, vec2: TPointD): TPointD; var inverseHypot: Double; begin Result.X := (vec1.X + vec2.X) * 0.5; Result.y := (vec1.Y + vec2.Y) * 0.5; inverseHypot := 1 / Hypot(Result.X, Result.Y); Result.X := Result.X * inverseHypot; Result.Y := Result.Y * inverseHypot; end; procedure MakeSymmetric(var val1, val2: double); begin val1 := (val1 + val2) * 0.5; val2 := val1; end; function GetUnitVector(const pt1, pt2: TPointD): TPointD; var dx, dy, inverseHypot: Double; begin if (pt1.x = pt2.x) and (pt1.y = pt2.y) then begin Result.X := 0; Result.Y := 0; Exit; end; dx := (pt2.X - pt1.X); dy := (pt2.Y - pt1.Y); inverseHypot := 1 / Hypot(dx, dy); dx := dx * inverseHypot; dy := dy * inverseHypot; Result.X := dx; Result.Y := dy; end; // GetSmoothPath - returns cubic bezier control points // parameters: 1. path for smoothing // 2. whether or not the smoothed path will closed // 3. percent smoothness (0..100) // 4. maximum dist control pts from path pts (0 = no limit) // 5. symmetric vs asymmmetric control pts function GetSmoothPath(const path: TPathD; pathIsClosed: Boolean; percentOffset, maxCtrlOffset: double; symmetric: Boolean): TPathD; var i, len, prev: integer; vec: TPointD; pl: TArrayOfDouble; unitVecs: TPathD; d, d1,d2: double; begin Result := nil; len := Length(path); if len < 3 then Exit; d := Max(0, Min(100, percentOffset))/200; if maxCtrlOffset <= 0 then maxCtrlOffset := MaxDouble; SetLength(Result, len *3 +1); prev := len-1; SetLength(pl, len); SetLength(unitVecs, len); for i := 0 to len -1 do begin pl[i] := Distance(path[prev], path[i]); unitVecs[i] := GetUnitVector(path[prev], path[i]); prev := i; end; Result[len*3] := path[0]; for i := 0 to len -1 do begin if i = len -1 then begin vec := GetAvgUnitVector(unitVecs[i], unitVecs[0]); d2 := pl[0]*d; end else begin vec := GetAvgUnitVector(unitVecs[i], unitVecs[i+1]); d2 := pl[i+1]*d; end; d1 := pl[i]*d; if symmetric then MakeSymmetric(d1, d2); if i = 0 then Result[len*3-1] := OffsetPoint(path[i], -vec.X * Min(maxCtrlOffset, d1), -vec.Y * Min(maxCtrlOffset, d1)) else Result[i*3-1] := OffsetPoint(path[i], -vec.X * Min(maxCtrlOffset, d1), -vec.Y * Min(maxCtrlOffset, d1)); Result[i*3] := path[i]; Result[i*3+1] := OffsetPoint(path[i], vec.X * Min(maxCtrlOffset, d2), vec.Y * Min(maxCtrlOffset, d2)); end; if not pathIsClosed then begin Result[1] := Result[0]; dec(len); Result[len*3-1] := Result[len*3]; SetLength(Result, Len*3 +1); end; end;
And here's what it produces ...
the path to smooth (black),
the cubic bezier control path produced by GetSmoothPath() (blue)
and the flattened cubic bezier path (2D graphics library of you choice required) (red).
var TPathD path; begin path := MakePath([190,120, 260,270, 560,120, 190,490]); path := GetSmoothPath(path, true, 20, 0, false); path := ThirdParty2DGraphicsLibrary.FlattenCBezier(path); end;
var TPathD path; begin path := MakePath([190,120, 260,270, 560,120, 190,490]); path := GetSmoothPath(path, true, 80, 0, false); path := ThirdParty2DGraphicsLibrary.FlattenCBezier(path); end;
On 5/20/2022 at 8:45 PM, A.M. Hoornweg said:The problem: The polygons may never intersect (
Edit: The best way to avoid intersections is to make sure you have enough data points before generating your curves.
- 4
-
5 hours ago, Dale M said:You just have dig for it under the hamburger icon at the top right, Account, Mark site read.
Thanks Dale. I have been doing that. I just find it somewhat tedious having to do that every time i visit DP. IMHO, having a "Mark site read" button at the bottom as in desktop view would be much more convenient. Cheers.
- 1
-
Please (as per title).
-
On 2/20/2022 at 3:54 AM, Bent Normann Olsen said:I have taken steps in removing the current edition. Sorry for any inconveniences. Perhaps it's just not ment to be.
16 hours ago, corneliusdavid said:I clicked on the link and it can't be found; searched for the title and couldn't be found either.
See above. While I also missed downloading and reading Normann's book, it seems he wasn't encouraged by the initial feedback. I think there's a lessen in that. Normann had put considerable effort into writing this book and uploaded it as a free resource and, from what I can glean from this thread, it was mostly of high quality.
-
4 hours ago, Anders Melander said:You don't need a plugin to receive items dragged from outlook. You just need to handle the correct clipboard format
That seems likely be the solution to Dave Nottage's problem, though it isn't the answer to his question 😁.
-
37 minutes ago, Dave Nottage said:As promising as that looked, it didn't help 🙂
Despite the lack of documentation on EVENT_OBJECT_DRAGSTART here:
https://docs.microsoft.com/en-us/windows/win32/winauto/event-constants
it seems likely that this event is only triggered by "UI Automation" Drag-and-Drop
https://docs.microsoft.com/en-us/windows/win32/winauto/ui-automation-support-for-drag-and-drop
-
37 minutes ago, Vincent Parrett said:I suspect that might not be using the standard windows drag and drop - more likely an OLE one.
Is there a difference between OLE and "the standard windows drag and drop"?
"The OLE DoDragDrop function calls this method (IDropSource::QueryContinueDrag) during a drag-and-drop operation."
https://docs.microsoft.com/en-us/windows/win32/api/oleidl/nn-oleidl-idropsource
Of course, this is very different to Delphi's custom drag drop stuff.
-
QuoteDetecting start of drag operations
guessing ...
startDragEvent := SetWinEventHook(EVENT_OBJECT_DRAGSTART, EVENT_OBJECT_DRAGSTART, 0, @DragStartEvent, 0, 0, WINEVENT_OUTOFCONTEXT); procedure DragStartEvent(hWinEventHook: THandle; event: DWORD; hwnd: HWND; idObject, idChild: Longint; idEventThread, dwmsEventTime: DWORD); stdcall; begin //do stuff end;
Note: All OLE drag events are initiated by DoDragDrop
https://docs.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-dodragdrop
Since the drag souce (IDropSource, IDataObject) is initiated by another process so you'll certainly need a system event hook.
-
On 2/2/2021 at 4:02 AM, Anders Melander said:Yes but it's a nasty mess. Better than nothing I guess.
I wholeheartedly agree with you Anders that TBitmap.AlphaFormat is broken and should be deprecated.
Not only does it not behave in an intuitive manner, but Premultiplying and UnPremultiplying images is (mildly) destructive.
But there's another potentially bigger problem - when writing an afDefined Bitmap to stream, UnPreMultiplyAlpha is called and hence the image will no longer be properly rendered.
ps: Isn't it fun digging up old threads 😜.
-
53 minutes ago, A.M. Hoornweg said:TargetImage.Transparent := True;
Delete this line. It's only (sort of) useful for images without alpha transparency.
- 1
Hextor - Hexadecimal editor and binary data analyzing toolkit
in I made this
Posted