• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

The PhotoSetup project (color settings + red-eye removal)

Started by Patrice Terrier, July 25, 2008, 04:34:07 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Patrice Terrier

PhotoSetup (The project)

This version supersede the previous one that was posted in the thread entitled "Written in PowerBASIC for Windows".



PhotoSetup is a GDImage project that allows you to edit the settings of your photography.
It can also autocrop a photography to adjust its size to a standard photo paper of 152 x 102 mm.
The ZI_FitImageToPaper API allows you to use another paper size, like 233 x 152 mm, if you want.

Note: When using autocrop, GDImage checks for the orientation of the phototography to create the new cropped image in such a way that it best fit the paper size.

You can figure how the image will fit into the default paper size of 152 x 102 mm, if you uncheck the "composited mode" and if the PhotoSetup window uses its default size of 800 x 600.

Specific features:

The "Disabled Window" mode
GDImage allows you to disabled a main window, while a child popup window is waiting for input.
You can see it when you use the "Select a new picture" button, or when you use "Crop to paper size" or "Save to file".

The disabled window becomes darker until the user complete the input.

The matching GDImage API are:

'//4.05 Create a Disabled Window that works with any control created directly with the API
  DECLARE FUNCTION ZI_CreateDW LIB "GDIMAGE.DLL" ALIAS "ZI_CreateDW" ( _
  BYVAL hParent AS LONG _
  ) AS LONG

'//4.05 Show the Disabled Window
  DECLARE SUB ZI_ShowDW LIB "GDIMAGE.DLL" ALIAS "ZI_ShowDW"( _
  BYVAL hDW AS LONG _
  )

'//4.05 Hide the Disabled Window
  DECLARE SUB ZI_HideDW LIB "GDIMAGE.DLL" ALIAS "ZI_HideDW" ( _
  BYVAL hDW AS LONG _
  )

You can use drag and drop between the Windows Explorer and the PhotoSetup window to select a specific picture.


This version allows you to try the GDImage's "anti-red-eye" feature (requires version 4.14+)
 
...

Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

TIP: to convert a picture to shade of gray set HUE to its minimum value.

BONUS:
There are many backgrounds for you to try!
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

Hi Patrice,

thank you for another nice program! It looks great as usually.

Just two little problems:

  • For higher resolutions, and even not so high such as 2848 x 2136, the resolution label is cut so not whole text is visible
  • The speed on my AMD Sempron 3400+ is not bad, but still a bit worse than in my favourite Picture Publisher 8 ( not much, but observable )

Take my complaints with reserve, I would not be able to do what you did even if I would press my head for long :)


Thanks,
Petr
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Patrice Terrier

#3
As for the resolution label, this is easy to fix:
just change
    hCtrl = zStaticLabelEx(gMainWnd, "", 14, 143, 64, 18, %ID_LIB_SIZE, SK_BTNTEXTCOLOR(), %BS_LABEL_LEFT, 1)
to this
    hCtrl = zStaticLabelEx(gMainWnd, "", 14, 143, 80, 18, %ID_LIB_SIZE, SK_BTNTEXTCOLOR(), %BS_LABEL_LEFT, 1)

As for the speed with large pictures 2848 x 2136 = 6 Mega pixels or larger, select the settings and use the "Apply" button, then try zoom and rotation and the speed should be quite fast ;)

The problem with multiple settings is that they are cumulative, I am using the built-in PowerBASIC MAT to multiply my matrix, would be interresting to compare with the GDIPLUS matrix function to see which one is faster, so far i gived the credit to PB without checking first with GDI+ .

Also it is important to consider that all drawings are antialiased, and that of course slowdowns the computation, but in that case i prefer to favor quality over speed.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

#4
Hi Patrice,

thanks for the tips! Worked well :)

Just one thing - PB MAT commands are great for code clarity, and reasonably fast. But for hi-performance applications ( like TBGL module for ThinBasic, written in PB/WIN 8.04 ) I prefer own routines for matrix handling. They are usually much faster, as they are optimized for specific matrix size. PB routines are more powerful, but also more general, which means some speed impact.

For example following code is very fast comparing to MAT equivalent ( especially in case of many "calls" ). I sometimes wonder why it is so fast as it does NOT:

  • use pointer
  • use assembly
  • use zero based arrays which are claimed to be faster

Key for speed in this case was usage of ARRAY ASSIGN, it is speed booster!

  MACRO INTERNAL_Matrix_Multiply3x3( MatrixRes, MatrixA, MatrixB )
    ARRAY ASSIGN MatrixRes() = MatrixA(1, 1) * MatrixB(1, 1) + MatrixA(1, 2) * MatrixB(2, 1) + MatrixA(1, 3) * MatrixB(3, 1), _
                               MatrixA(2, 1) * MatrixB(1, 1) + MatrixA(2, 2) * MatrixB(2, 1) + MatrixA(2, 3) * MatrixB(3, 1), _
                               MatrixA(3, 1) * MatrixB(1, 1) + MatrixA(3, 2) * MatrixB(2, 1) + MatrixA(3, 3) * MatrixB(3, 1), _
                               MatrixA(1, 1) * MatrixB(1, 2) + MatrixA(1, 2) * MatrixB(2, 2) + MatrixA(1, 3) * MatrixB(3, 2), _
                               MatrixA(2, 1) * MatrixB(1, 2) + MatrixA(2, 2) * MatrixB(2, 2) + MatrixA(2, 3) * MatrixB(3, 2), _
                               MatrixA(3, 1) * MatrixB(1, 2) + MatrixA(3, 2) * MatrixB(2, 2) + MatrixA(3, 3) * MatrixB(3, 2), _
                               MatrixA(1, 1) * MatrixB(1, 3) + MatrixA(1, 2) * MatrixB(2, 3) + MatrixA(1, 3) * MatrixB(3, 3), _
                               MatrixA(2, 1) * MatrixB(1, 3) + MatrixA(2, 2) * MatrixB(2, 3) + MatrixA(2, 3) * MatrixB(3, 3), _
                               MatrixA(3, 1) * MatrixB(1, 3) + MatrixA(3, 2) * MatrixB(2, 3) + MatrixA(3, 3) * MatrixB(3, 3)

  END MACRO



Thanks,
Petr
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Patrice Terrier

#5
I have also my own set of Matrix functions as you can see it in the pbDex3D project here
However i didn't benchmark it against the PB's built-in MAT function.
I shall make a test for comparison purpose and follow your advice of using "Array Assign".
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#6
Petr,

If you want to boost the preview settings, you can change this in the source code of PhotoSetup.

SUB UseThisPhoto(BYVAL sUsePhoto AS STRING, BYVAL bReset AS LONG)
    LOCAL lpr AS RECT, rZoomValue AS SINGLE
    LOCAL nHbitmap, nW, nH, nX, nY, nSizeX, nSizeY AS LONG

    '// Make sure to disable the crop rectangle if any
    IF ZI_GetToolCropStatus(gnCtrl) THEN ZI_DisableCropRectangle(gnCtrl)

    CALL ZI_GetImageSizeFromFile((sUsePhoto), gnTrueWidth, gnTrueHeight)
    nW = MAX&(gnTrueWidth, gnTrueHeight):
IF nW > 1024 THEN nW = 1024
    nHbitmap = ZI_FitBitmapFromFile((sUsePhoto), nW, nW)

Try with a value of 512 instead of 1024.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

Thanks Patrice,

it works much faster now.


Petr
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Patrice Terrier

Petr,

In my case ARRAY ASSIGN doesn't make any difference.
I am using a 5x5 matrix and it involves much more computation than in your example

This is the kind of matrix being used in GDImage:

' Fill the color matrix                                                                         
' Red           Green         Blue          Alpha         W                   
  c2(0, 0) = R: c2(1, 0) = 0: c2(2, 0) = 0: c2(3, 0) = 0: c2(4, 0) = 0 ' Red 
  c2(0, 1) = 0: c2(1, 1) = G: c2(2, 1) = 0: c2(3, 1) = 0: c2(4, 1) = 0 ' Green
  c2(0, 2) = 0: c2(1, 2) = 0: c2(2, 2) = B: c2(3, 2) = 0: c2(4, 2) = 0 ' Blue
  c2(0, 3) = 0: c2(1, 3) = 0: c2(2, 3) = 0: c2(3, 3) = A: c2(4, 3) = 0 ' Alpha
  c2(0, 4) = 0: c2(1, 4) = 0: c2(2, 4) = 0: c2(3, 4) = 0: c2(4, 4) = W ' W   

Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#9
Attached is the GDImage.dll using Charles's code instead of the built-in PB MAT function. 


SUB MatrixMul5x5FPU(BYREF mr() AS SINGLE, BYREF m1() AS SINGLE, BYREF m2() AS SINGLE )
DIM p AS SINGLE PTR

p=VARPTR(m1(0))
! mov ecx,eax
p=VARPTR(m2(0))
! mov edx,eax
p=VARPTR(mr(0))

block:
! call column
! call column
! call column
! call column
! call column
EXIT SUB

column:
! call cell
! call cell
! call cell
! call cell
! call cell
! add edx,20
! sub ecx,20
! ret

cell: ' row A * column B
! fld   dword ptr [ecx   ]
! fmul  dword ptr [edx   ]
! fld   dword ptr [ecx+20]
! fmul  dword ptr [edx+04]
! fld   dword ptr [ecx+40]
! fmul  dword ptr [edx+08]
! fld   dword ptr [ecx+60]
! fmul  dword ptr [edx+12]
! fld   dword ptr [ecx+80]
! fmul  dword ptr [edx+16]
! faddp st(1),st(0)
! faddp st(1),st(0)
! faddp st(1),st(0)
! faddp st(1),st(0)
! fstp  dword ptr [eax]
! add   eax,4
! add   ecx,4
! ret
END SUB



Note: While changing the settings, GDImage computes the new matrix in real time to update the display and the matching DIB section, not a trivial task as you could imagine.

When you use the "APPLY" button the settings are frozen and thus zoom and rotation are working again at full speed.

I am using cumulative effects directly on the real bitmap, and this would be of course much faster if i would use a smaller bitmap preview when building the initial ZI_FitBitmapFromFile.
 

Thank you Charles!

Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

Hi Patrice,

I am sorry my solution did not worked for you, I guess the 5x5 is too big. For 3x3 it had nice effect for me.

Charles optimizations ... this is always great stuff!


Petr
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Patrice Terrier

The PhotoSetup project has been updated to let you try the new "Remove red-eye" feature.

The ZIP file is attached to the first post of this thread, and it is provided with a "red_eye.jpg" picture to play with.

Screen shot:



In this example, the right eye has been corrected while the other on the left is unchanged.

To use it, click on the "Remove red-eye" button, then move the cursor hover the eye and use the ellipse to delimit the section (you can resize it using the rubber band). Once done click on the right mouse button to popup the contextual menu and select "Apply".

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

The first post of this thread has been updated, to fix the ZIP file corruption caused by the "Server Collapse".

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com