From 1189c52ae1b336742cbc2796be5f1e3ee4b29f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Tue, 24 Apr 2012 12:33:52 +0000 Subject: [PATCH] [EXAMPLES] * NEW: Fix and enhance PhotoTouch example. git-svn-id: svn://localhost/gambas/trunk@4667 867c0c6c-44f3-4631-809d-bfa615b0a4ec --- examples/examples/Image/PhotoTouch/.info | 12 +- .../examples/Image/PhotoTouch/.lang/fr.mo | Bin 414 -> 1712 bytes .../examples/Image/PhotoTouch/.lang/fr.po | 97 ++++++++- examples/examples/Image/PhotoTouch/.project | 1 + .../Image/PhotoTouch/.src/CAnimation.class | 48 +++++ .../Image/PhotoTouch/.src/CButton.class | 96 ++++++--- .../Image/PhotoTouch/.src/FBrightness.class | 11 +- .../Image/PhotoTouch/.src/FBrightness.form | 12 +- .../Image/PhotoTouch/.src/FMain.class | 199 ++++++++++++++---- .../examples/Image/PhotoTouch/.src/FMain.form | 1 + .../Image/PhotoTouch/.src/FResize.class | 44 ++++ .../Image/PhotoTouch/.src/FResize.form | 38 ++++ .../Image/PhotoTouch/.src/FScissors.class | 14 +- examples/examples/Image/PhotoTouch/.startup | 1 + .../PhotoTouch/{control.png => balance.png} | Bin examples/examples/Image/PhotoTouch/blur.png | Bin 0 -> 1924 bytes .../examples/Image/PhotoTouch/despeckle.png | Bin 0 -> 2604 bytes examples/examples/Image/PhotoTouch/hflip.png | Bin 0 -> 1529 bytes examples/examples/Image/PhotoTouch/invert.png | Bin 0 -> 3064 bytes examples/examples/Image/PhotoTouch/magic.png | Bin 0 -> 1728 bytes .../examples/Image/PhotoTouch/normalize.png | Bin 0 -> 1439 bytes examples/examples/Image/PhotoTouch/oil.png | Bin 0 -> 1668 bytes examples/examples/Image/PhotoTouch/resize.png | Bin 0 -> 1301 bytes .../examples/Image/PhotoTouch/sharpen.png | Bin 0 -> 2242 bytes examples/examples/Image/PhotoTouch/vflip.png | Bin 0 -> 1434 bytes 25 files changed, 474 insertions(+), 100 deletions(-) create mode 100644 examples/examples/Image/PhotoTouch/.src/CAnimation.class create mode 100644 examples/examples/Image/PhotoTouch/.src/FResize.class create mode 100644 examples/examples/Image/PhotoTouch/.src/FResize.form rename examples/examples/Image/PhotoTouch/{control.png => balance.png} (100%) create mode 100644 examples/examples/Image/PhotoTouch/blur.png create mode 100644 examples/examples/Image/PhotoTouch/despeckle.png create mode 100644 examples/examples/Image/PhotoTouch/hflip.png create mode 100644 examples/examples/Image/PhotoTouch/invert.png create mode 100644 examples/examples/Image/PhotoTouch/magic.png create mode 100644 examples/examples/Image/PhotoTouch/normalize.png create mode 100644 examples/examples/Image/PhotoTouch/oil.png create mode 100644 examples/examples/Image/PhotoTouch/resize.png create mode 100644 examples/examples/Image/PhotoTouch/sharpen.png create mode 100644 examples/examples/Image/PhotoTouch/vflip.png diff --git a/examples/examples/Image/PhotoTouch/.info b/examples/examples/Image/PhotoTouch/.info index 4ec779cb0..1610227dd 100644 --- a/examples/examples/Image/PhotoTouch/.info +++ b/examples/examples/Image/PhotoTouch/.info @@ -9,6 +9,14 @@ Image p Image +Opacity +p +f + +Highlight +p +b + _new m @@ -29,10 +37,6 @@ DrawingArea_DblClick m -Timer_Timer -m - - DrawingArea_Draw m diff --git a/examples/examples/Image/PhotoTouch/.lang/fr.mo b/examples/examples/Image/PhotoTouch/.lang/fr.mo index 28b19914d9b28740ed155f009739833525a63057..dc411a685372e89f958267d5c73e0b2c90bd4f17 100644 GIT binary patch literal 1712 zcmZXTO^h2g6vs^|9}ORcLirLPt5R7|HEps&VhIIxnoLSWzM5<*wKsRhNnAYk;PGtP zMdE45-+?E= z@4;i>FW@uaZy@>m2PFG{L9#yrr;mZhz{kOp;B(+9kaWBa()kc1eN*r$@CHc!KLN?^ z7WgQ58+-#feF>7EpAeM3{|Zw4Kk!4k{{-p$f8Z-1dx)_Yfmgxj!7Y&djX(}w1*r~u zAl2^{NPhQ0()TU+B={pp=YL-DFYtA&{|Cw6Ye@POcn+kvW03r1AnCacQk<_qs`EZb zS44Z{_i$jlj88d|Zn{?*lp_tQ5$U0ty?{wMQ{7Saa!}0=2i+INqCvTk4jLygQO0sW zetAE%pgdSuc$*5ZVjf%PWbBnS?4r=Z#FAaqg<~yeGpltgDb-mMS-l_#jZ<*R(p~SmFAgH#w#=DayEkj zyId&G#xk`#lINL>Kh!eEIw$+F^}GAnZr{eAExS zy$fNxJ&q=m_h4$~1uihymLhHPUO2ckC2i+>y$f2MwQjz)Y4TdX+mF_XG|tv*E!?g& z2)CO-x0fILbD73%y+hS;x%BT&w>!bs+Kyz+qzfVw+XPqI4X)YoMCm_aelOK&8uPBAippZ&0;6MnA1k delta 159 zcmdnMJCC{ko)F7a1|VPtVi_Pd0b*7l_5orLNC0AXAWj5gkeW;&mSbdK$OY0M@g5+X z6G%@1(m(`O1Ed(3Km-UlCFUgNC8shtmzFRD6y;~7CYR`Xrs#&H78Pga=S^P0ylHYO TOSBM7nakmo$@!%PsYMI`+}0b` diff --git a/examples/examples/Image/PhotoTouch/.lang/fr.po b/examples/examples/Image/PhotoTouch/.lang/fr.po index 1047b28bc..749746065 100644 --- a/examples/examples/Image/PhotoTouch/.lang/fr.po +++ b/examples/examples/Image/PhotoTouch/.lang/fr.po @@ -6,19 +6,108 @@ msgstr "" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: FBrightness.form:55 +#: FMain.class:107 +msgid "Automatic correction" +msgstr "Correction automatique" + +#: FBrightness.form:56 FMain.class:107 msgid "Balance" msgstr "Balance" +#: FMain.class:107 +msgid "Blur" +msgstr "Flou" + +#: FMain.class:107 +msgid "Crop image" +msgstr "Découper l'image" + #: FScissors.form:19 msgid "Cut" msgstr "Découper" -#: .project:1 -msgid "Retouche Photo" -msgstr "" +#: FMain.class:107 +msgid "Fit to window" +msgstr "Zoom à la taille de l'écran" + +#: FMain.class:107 +msgid "Flip horizontally" +msgstr "Retourner horizontalement" + +#: FMain.class:107 +msgid "Flip vertically" +msgstr "Retourner verticalement" + +#: FMain.class:107 +msgid "Invert" +msgstr "Inverser" + +#: FMain.class:55 +msgid "No image in directory" +msgstr "Aucune image dans ce répertoire" + +#: FMain.class:107 +msgid "Normalize" +msgstr "Normaliser" + +#: FMain.class:107 +msgid "Oil painting effect" +msgstr "Effet de peinture à l'huile" + +#: FMain.class:107 +msgid "Quit" +msgstr "Quitter" + +#: FMain.class:107 +msgid "Remove speckles" +msgstr "Enlever les tâches" + +#: FMain.class:107 FResize.form:40 +msgid "Resize" +msgstr "Redimensionner" + +#: FMain.class:107 +msgid "Rotate left" +msgstr "Rotation vers la gauche" + +#: FMain.class:107 +msgid "Rotate right" +msgstr "Rotation vers la droite" + +#: FMain.class:107 +msgid "Select photo directory" +msgstr "Choisir le répertoire des photographies" + +#: FMain.class:107 +msgid "Sharpen" +msgstr "Netteté" + +#: .project:1 +msgid "Simple Photo Editor" +msgstr "Editeur de photographie simplifié" + +#: FMain.class:58 +msgid "Unable to load image" +msgstr "Impossible de charger l'image" + +#: FMain.class:107 +msgid "Undo all changes" +msgstr "Annuler tous les changements" + +#: FMain.class:107 +msgid "Zoom 100%" +msgstr "Zoom 100%" + +#: FMain.class:107 +msgid "Zoom in" +msgstr "Zoom avant" + +#: FMain.class:107 +msgid "Zoom out" +msgstr "Zoom arrière" diff --git a/examples/examples/Image/PhotoTouch/.project b/examples/examples/Image/PhotoTouch/.project index 6e320d717..c166b2167 100644 --- a/examples/examples/Image/PhotoTouch/.project +++ b/examples/examples/Image/PhotoTouch/.project @@ -9,6 +9,7 @@ Component=gb.image Component=gb.qt4 Component=gb.form Component=gb.desktop +Component=gb.settings Component=gb.image.effect Authors="Benoît Minisini" TabSize=2 diff --git a/examples/examples/Image/PhotoTouch/.src/CAnimation.class b/examples/examples/Image/PhotoTouch/.src/CAnimation.class new file mode 100644 index 000000000..8a25f7d8e --- /dev/null +++ b/examples/examples/Image/PhotoTouch/.src/CAnimation.class @@ -0,0 +1,48 @@ +' Gambas class file + +Private $hObject As Object +Private $sProperty As String +Private $fTarget As Float +Private $fTime As Float +Private $hTimer As Timer + +Public Sub _new(hObject As Control, sProperty As String, fTarget As Float, iTime As Integer) + + $hObject = hObject + $sProperty = sProperty + $fTarget = fTarget + $fTime = Timer + iTime / 1000 + + $hTimer = New Timer As "Timer" + $hTimer.Delay = 50 + $hTimer.Start + +End + +Public Sub Timer_Timer() + + Dim fValue As Float + Dim iSign As Integer + + fValue = Object.GetProperty($hObject, $sProperty) + + iSign = Sgn($fTarget - fValue) + fValue += ($fTarget - fValue) / (1000 * ($fTime - Timer) / $hTimer.Delay) + If Sgn($fTarget - fValue) <> iSign Then + Object.SetProperty($hObject, $sProperty, $fTarget) + {Stop} + Else + Object.SetProperty($hObject, $sProperty, fValue) + Endif + +Catch + + {Stop} + +End + +Public Sub Stop() + + $hTimer = Null + +End diff --git a/examples/examples/Image/PhotoTouch/.src/CButton.class b/examples/examples/Image/PhotoTouch/.src/CButton.class index 7ed62f1b8..4b2c4a765 100644 --- a/examples/examples/Image/PhotoTouch/.src/CButton.class +++ b/examples/examples/Image/PhotoTouch/.src/CButton.class @@ -7,22 +7,26 @@ Inherits DrawingArea Event Click Property Image As Image +Property Opacity As Float +Property Highlight As Boolean -Private Const MIN_OPACITY As Float = 0.3 -Private Const MAX_OPACITY As Float = 0.8 +Private MIN_OPACITY As Float = 0.2 +Private MAX_OPACITY As Float = 0.8 Private $hObs As Observer Private $hImage As Image Private $hDraw As Image Private $bInside As Boolean -Private $hTimer As Timer +'Private $hTimer As Timer +Private $hAnim As CAnimation Private $fOpacity As Float = MIN_OPACITY +Private $bHighlight As Boolean Public Sub _new() $hObs = New Observer(Me) As "DrawingArea" - $hTimer = New Timer As "Timer" - $hTimer.Delay = 50 + '$hTimer = New Timer As "Timer" + '$hTimer.Delay = 50 Me.Mouse = Mouse.Pointing End @@ -30,14 +34,16 @@ End Public Sub DrawingArea_Enter() $bInside = True - $hTimer.Start + Try $hAnim.Stop + $hAnim = New CAnimation(Me, "Opacity", MAX_OPACITY, 250) End Public Sub DrawingArea_Leave() $bInside = False - $hTimer.Start + Try $hAnim.Stop + $hAnim = New CAnimation(Me, "Opacity", MIN_OPACITY, 250) End @@ -54,30 +60,37 @@ Public Sub DrawingArea_DblClick() End -Public Sub Timer_Timer() - - If $bInside Then - $fOpacity = Min(MAX_OPACITY, $fOpacity + 0.1) - If $fOpacity >= MAX_OPACITY Then - $hTimer.Stop - Endif - Else - $fOpacity = Max(MIN_OPACITY, $fOpacity - 0.1) - If $fOpacity <= MIN_OPACITY Then - $hTimer.Stop - Endif - Endif - - SetOpacity - -End +' Public Sub Timer_Timer() +' +' If $bInside Then +' $fOpacity = Min(MAX_OPACITY, $fOpacity + 0.1) +' If $fOpacity >= MAX_OPACITY Then +' $hTimer.Stop +' Endif +' Else +' $fOpacity = Max(MIN_OPACITY, $fOpacity - 0.1) +' If $fOpacity <= MIN_OPACITY Then +' $hTimer.Stop +' Endif +' Endif +' +' SetOpacity +' +' End Public Sub DrawingArea_Draw() If Not $hImage Then Return - Draw.Image($hDraw, 0, 0, Me.W, Me.H) + Draw.Image($hDraw, 4, 4) + If $bHighlight Then + Paint.Begin(Me) + Paint.Brush = Paint.Color(Color.SetAlpha(Color.White, 192)) + Paint.Rectangle(0, 0, Me.W, Me.H) + Paint.Fill + Paint.End + Endif End @@ -89,7 +102,7 @@ End Private Sub Image_Write(Value As Image) - $hImage = Value + $hImage = Value.Stretch(Me.W - 8, Me.H - 8) SetOpacity End @@ -101,3 +114,34 @@ Private Sub SetOpacity() Me.Refresh End + +Private Function Opacity_Read() As Float + + Return $fOpacity + +End + +Private Sub Opacity_Write(Value As Float) + + $fOpacity = Max(0, Min(1, Value)) + SetOpacity + +End + +Private Function Highlight_Read() As Boolean + + Return $bHighlight + +End + +Private Sub Highlight_Write(Value As Boolean) + + $bHighlight = Value + 'MIN_OPACITY = If($bHighlight, 0.6, 0.2) + 'If Not $bInside Then + ' Try $hAnim.Stop + ' $hAnim = New CAnimation(Me, "Opacity", MIN_OPACITY, 250) + 'Endif + Me.Refresh + +End diff --git a/examples/examples/Image/PhotoTouch/.src/FBrightness.class b/examples/examples/Image/PhotoTouch/.src/FBrightness.class index 4a9eb368f..0bf6837ba 100644 --- a/examples/examples/Image/PhotoTouch/.src/FBrightness.class +++ b/examples/examples/Image/PhotoTouch/.src/FBrightness.class @@ -12,11 +12,11 @@ Private btnApply As CButton Public Sub _new() btnUndo = New CButton(Me) As "btnUndo" - btnUndo.Move(Me.W - 128 - Desktop.Scale * 3, Desktop.Scale * 3, 64, 64) + btnUndo.Move(Me.W - 96 - Desktop.Scale * 4, Desktop.Scale * 3, 48, 48) btnUndo.Image = Image.Load("undo.png") btnApply = New CButton(Me) As "btnApply" - btnApply.Move(btnUndo.X + btnUndo.W + Desktop.Scale, btnUndo.Y, 64, 64) + btnApply.Move(btnUndo.X + btnUndo.W + Desktop.Scale, btnUndo.Y, 48, 48) btnApply.Image = Image.Load("ok.png") End @@ -29,12 +29,6 @@ Public Sub Form_Open() End -Public Sub Form_Close() - - FMain.End - -End - Public Sub btnUndo_Click() $bNoChange = True @@ -49,7 +43,6 @@ End Public Sub btnApply_Click() FMain.Apply - Me.Close End diff --git a/examples/examples/Image/PhotoTouch/.src/FBrightness.form b/examples/examples/Image/PhotoTouch/.src/FBrightness.form index 5b9072a3a..a6e01e08e 100644 --- a/examples/examples/Image/PhotoTouch/.src/FBrightness.form +++ b/examples/examples/Image/PhotoTouch/.src/FBrightness.form @@ -11,25 +11,25 @@ MoveScaled(1,1,72,46) Background = &H000000& { PictureBox1 PictureBox - MoveScaled(2,10,10,10) + MoveScaled(2,11,8,8) Picture = Picture["luminosity.png"] Stretch = True Alignment = Align.Center } { PictureBox2 PictureBox - MoveScaled(2,22,10,10) + MoveScaled(2,23,8,8) Picture = Picture["contrast.png"] Stretch = True Alignment = Align.Center } { sldBrightness Slider Balance Name = "sldBrightness" - MoveScaled(15,13,53,3) + MoveScaled(13,13,55,3) Value = 50 } { sldContrast Slider Balance Name = "sldContrast" - MoveScaled(15,25,53,3) + MoveScaled(13,25,55,3) Value = 50 } { Label1 Label @@ -40,14 +40,14 @@ Text = ("Balance") } { PictureBox3 PictureBox - MoveScaled(2,34,10,10) + MoveScaled(2,35,8,8) Picture = Picture["gamma.png"] Stretch = True Alignment = Align.Center } { sldGamma Slider Balance Name = "sldGamma" - MoveScaled(15,37,53,3) + MoveScaled(13,37,55,3) Value = 50 } } diff --git a/examples/examples/Image/PhotoTouch/.src/FMain.class b/examples/examples/Image/PhotoTouch/.src/FMain.class index 8b922a7bd..b1f751857 100644 --- a/examples/examples/Image/PhotoTouch/.src/FMain.class +++ b/examples/examples/Image/PhotoTouch/.src/FMain.class @@ -1,6 +1,7 @@ ' Gambas class file -Private CACHE_DIR As String = "~/.cache/gambas/PhotoTouch" +Private CACHE_ROOT As String = "~/.cache/gambas/PhotoTouch" +Private CACHE_DIR As String Private $aPath As String[] Private $sPath As String @@ -13,6 +14,7 @@ Private $fZoom As Float = 1 Private $sInfo As String Private $sMode As String Private $bModify As Boolean +Private $cButton As New Collection Private $MX As Integer Private $MY As Integer @@ -73,26 +75,52 @@ Public Sub _new() Dim sImg As String Dim hButton As CButton Dim hPanel As Panel + Dim cTooltip As Collection Application.MainWindow = Me - Try Mkdir File.Dir(File.Dir(cache_dir)) - Try Mkdir File.Dir(cache_dir) - Try Mkdir CACHE_DIR + Try Mkdir File.Dir(File.Dir(CACHE_ROOT)) + Try Mkdir File.Dir(CACHE_ROOT) + Try Mkdir CACHE_ROOT - For Each sImg In ["usb", "-", "zoom-in", "zoom-out", "zoom-original", "zoom-fit", "-", "rotate-left", "rotate-right", "-", "scissors", "luminosity", "<->", "undo", "quit"] + cTooltip = [ + "usb": ("Select photo directory"), + "zoom-in": ("Zoom in"), + "zoom-out": ("Zoom out"), + "zoom-original": ("Zoom 100%"), + "zoom-fit": ("Fit to window"), + "hflip": ("Flip horizontally"), + "vflip": ("Flip vertically"), + "rotate-left": ("Rotate left"), + "rotate-right": ("Rotate right"), + "magic": ("Automatic correction"), + "invert": ("Invert"), + "blur": ("Blur"), + "sharpen": ("Sharpen"), + "normalize": ("Normalize"), + "despeckle": ("Remove speckles"), + "oil": ("Oil painting effect"), + "scissors": ("Crop image"), + "balance": ("Balance"), + "resize": ("Resize"), + "undo": ("Undo all changes"), + "quit": ("Quit")] + + For Each sImg In ["usb", "-", "zoom-in", "zoom-out", "zoom-original", "zoom-fit", "-", "hflip", "vflip", "rotate-left", "rotate-right", "-", "magic", "invert", "blur", "sharpen", "normalize", "despeckle", "oil", "-", "scissors", "resize", "balance", "<->", "undo", "quit"] If sImg = "<->" Then hPanel = New Panel(panToolbar) hPanel.Expand = True - hPanel.Resize(8, 64) + hPanel.Resize(8, 48) Else If sImg = "-" Then hPanel = New Panel(panToolbar) - hPanel.Resize(16, 64) + hPanel.Resize(8, 48) Else hButton = New CButton(panToolbar) As "Button" - hButton.Resize(64, 64) + hButton.Resize(48, 48) hButton.Image = Image.Load(sImg & ".png") hButton.Tag = sImg + hButton.Tooltip = cTooltip[sImg] + $cButton[hButton.Tag] = hButton Endif Next @@ -111,12 +139,6 @@ Public Sub _new() End -Public Sub Form_Open() - - SetDir(User.Home) - -End - Public Sub svwImage_Draw() Dim X As Integer @@ -204,7 +226,7 @@ End Public Sub Form_Resize() - panToolbar.Move(0, 0, Me.W, 64 + Desktop.Scale * 2) + panToolbar.Move(0, 0, Me.W, 48 + Desktop.Scale * 2) dwgInfo.Move(8, Me.H - dwgInfo.H, Me.W, dwgInfo.H) btnPrev.Move(8, (Me.H - btnPrev.H) / 2) btnNext.Move(Me.W - 8 - btnNext.W, (Me.H - btnNext.H) / 2) @@ -235,6 +257,7 @@ Private Sub UpdateZoom() svwImage.ResizeContents($hImage.W * $fZoom, $hImage.H * $fZoom) svwImage.Scroll(X * svwImage.ScrollW - svwImage.ClientW / 2, Y * svwImage.ScrollH - svwImage.ClientH / 2) + dwgInfo.Refresh Me.Refresh End @@ -263,9 +286,16 @@ End Public Sub SetMode(sMode As String) If $sMode Then + $cButton[$sMode].Highlight = False Cancel - FBrightness.Close - FScissors.Close + Select Case $sMode + Case "balance" + FBrightness.Close + Case "scissors" + FScissors.Close + Case "resize" + FResize.Close + End Select Endif If sMode = $sMode Then @@ -273,12 +303,20 @@ Public Sub SetMode(sMode As String) Return Endif - Select Case sMode - Case "luminosity" - FBrightness.Show - Case "scissors" - FScissors.Show - End Select + If sMode Then + + $cButton[sMode].Highlight = True + + Select Case sMode + Case "balance" + FBrightness.Show + Case "scissors" + FScissors.Show + Case "resize" + FResize.Show + End Select + + Endif $sMode = sMode @@ -311,27 +349,13 @@ Private Sub Action(sAction As String) Case "zoom-fit" SetZoom(0) - Case "rotate-left" - If Not $hImage Then Return - $hImage = $hImage.Rotate(Pi(0.5)) - $bModify = True - 'SaveImage - UpdateZoom - - Case "rotate-right" - If Not $hImage Then Return - $hImage = $hImage.Rotate(Pi(-0.5)) - $bModify = True - 'SaveImage - UpdateZoom - Case "quit" SetMode("") SaveImage - If Dir(CACHE_DIR).Count Then Desktop.Open(CACHE_DIR) + If Exist(CACHE_DIR) Then Desktop.Open(CACHE_DIR) Me.Close - Case "luminosity", "scissors" + Case "balance", "scissors", "resize" If Not $hImage Then Return SetMode(sAction) @@ -345,6 +369,43 @@ Private Sub Action(sAction As String) LoadImage(True) RemoveImage + Case Else + + If Not $hImage Then Return + + SetMode("") + + Select Case sAction + Case "hflip" + $hImage.Mirror(True, False) + Case "vflip" + $hImage.Mirror(False, True) + Case "rotate-left" + $hImage = $hImage.Rotate(Pi(0.5)) + Case "rotate-right" + $hImage = $hImage.Rotate(Pi(-0.5)) + Case "oil" + $hImage = ImageMagick("-paint 4") '$hImage.OilPaint() + Case "magic" + $hImage = ImageMagick("-auto-gamma -auto-level") + Case "invert" + $hImage.Invert() + 'Case "equalize" + ' $hImage = ImageMagick("-equalize") + Case "despeckle" + $hImage = ImageMagick("-despeckle") + Case "normalize" + $hImage = ImageMagick("-normalize") + Case "blur" + $hImage = ImageMagick("-blur 8") '$hImage.OilPaint() + Case "sharpen" + $hImage = ImageMagick("-sharpen 8") '$hImage.OilPaint() + + End Select + + $bModify = True + UpdateZoom + End Select End @@ -381,7 +442,7 @@ Public Sub dwgInfo_Draw() ' Paint.Fill Paint.LineWidth = 1 Paint.Brush = Paint.Color(Color.SetAlpha(Color.White, 192)) - Paint.DrawText($sInfo, 0, 0, dwgInfo.W, dwgInfo.H, Align.Left) + Paint.DrawText($sInfo & " - " & Format($fZoom, "0%"), 0, 0, dwgInfo.W, dwgInfo.H, Align.Left) End @@ -415,6 +476,7 @@ End Public Sub Apply() $hTemp = $hImage + {End} End @@ -469,13 +531,34 @@ Public Sub Cut() End +Public Sub Stretch(W As Integer, H As Integer) + + $hImage = $hImage.Stretch(W, H) + $bModify = True + $hTemp = $hImage + Me.End + SetZoom(0) + +End + + +Public Sub Form_Activate() + + If $sDir = "" Then SetDir(Settings["Directory", User.Home]) + +End + + Private Sub SetDir(sDir As String) Inc Application.Busy - Shell "cd " & Shell(CACHE_DIR) & "; rm -f *" Wait + 'Shell "cd " & Shell(CACHE_DIR) & "; rm -f *" Wait + + CACHE_DIR = CACHE_ROOT &/ Replace(sDir, "/", ":") $sDir = sDir + Settings["Directory"] = $sDir $aPath = New String[] Try $aPath = Dir(sDir, "*.{jpg,JPG,jpeg,JPEG,png,PNG,bmp,BMP,gig,GIF}").Sort() $iIndex = 0 @@ -485,13 +568,15 @@ Private Sub SetDir(sDir As String) End -Private Sub SaveImage() +Private Sub SaveImage() As String If Not $hImage Then Return If Not $bModify Then Return - $hImage.Save(CACHE_DIR &/ File.Name($sPath)) + Try Mkdir CACHE_DIR + $hImage.Save(CACHE_DIR &/ File.Name($sPath), 80) $bModify = False + Return CACHE_DIR &/ File.Name($sPath) Catch @@ -501,6 +586,32 @@ End Private Sub RemoveImage() - Try Kill CACHE_DIR &/ File.Name($sPath) + Kill CACHE_DIR &/ File.Name($sPath) + If Dir(CACHE_DIR).Count = 0 Then Rmdir CACHE_DIR + +Catch + +End + +Private Sub ImageMagick(sCommand As String) As Image + + Dim sPath, sPath2 As String + Dim hImage As Image + + Inc Application.Busy + + sPath = File.SetExt(Temp$("image"), File.Ext($sPath)) + sPath2 = File.SetExt(Temp$("image2"), File.Ext($sPath)) + + $hImage.Save(sPath, 100) + + Shell "convert " & Shell(sPath) & " " & sCommand & " " & Shell(sPath2) Wait + hImage = Image.Load(sPath2) + Kill sPath + Kill sPath2 + + Dec Application.Busy + + Return hImage End diff --git a/examples/examples/Image/PhotoTouch/.src/FMain.form b/examples/examples/Image/PhotoTouch/.src/FMain.form index 908d8a00a..3d64d17cd 100644 --- a/examples/examples/Image/PhotoTouch/.src/FMain.form +++ b/examples/examples/Image/PhotoTouch/.src/FMain.form @@ -2,6 +2,7 @@ { Form Form MoveScaled(0,0,82,72) + Icon = Picture["icon.png"] Border = False Maximized = True Arrangement = Arrange.Fill diff --git a/examples/examples/Image/PhotoTouch/.src/FResize.class b/examples/examples/Image/PhotoTouch/.src/FResize.class new file mode 100644 index 000000000..d286e9102 --- /dev/null +++ b/examples/examples/Image/PhotoTouch/.src/FResize.class @@ -0,0 +1,44 @@ +' Gambas class file + +Private $aSize As Float[] = [1 / 4, 1 / 3, 1 / 2, 2 / 3, 3 / 4, 1] +Private btnApply As CButton + +Public Sub sldResize_Change() + + Dim W, H As Integer + + With FMain.GetImage() + W = .W * $aSize[sldResize.Value] + H = .H * $aSize[sldResize.Value] + End With + lblSize.Text = Format($aSize[sldResize.Value], "0%") & " - " & W & " x " & H + +End + +Public Sub _new() + + btnApply = New CButton(Me) As "btnApply" + btnApply.Move(Me.W - 48 - Desktop.Scale * 2, Desktop.Scale * 2, 48, 48) + btnApply.Image = Image.Load("ok.png") + +End + +Public Sub Form_Open() + + Me.Center + sldResize_Change + +End + +Public Sub btnApply_Click() + + Dim W, H As Integer + + With FMain.GetImage() + W = .W * $aSize[sldResize.Value] + H = .H * $aSize[sldResize.Value] + End With + + FMain.Stretch(W, H) + +End diff --git a/examples/examples/Image/PhotoTouch/.src/FResize.form b/examples/examples/Image/PhotoTouch/.src/FResize.form new file mode 100644 index 000000000..ebb55f266 --- /dev/null +++ b/examples/examples/Image/PhotoTouch/.src/FResize.form @@ -0,0 +1,38 @@ +# Gambas Form File 3.0 + +{ Form Form + MoveScaled(0,0,55,24) + Background = &HFFFFFF& + Border = False + Stacking = Window.Above + SkipTaskbar = True + Opacity = 50 + { panBrightness Panel + MoveScaled(1,1,53,22) + Background = &H000000& + { PictureBox1 PictureBox + MoveScaled(2,11,8,8) + Picture = Picture["resize.png"] + Stretch = True + Alignment = Align.Center + } + { sldResize Slider + MoveScaled(13,11,36,3) + MaxValue = 5 + Value = 5 + } + { lblTitle Label + MoveScaled(2,2,52,6) + Font = Font["Bold,+5"] + Foreground = Color.TextBackground + AutoResize = True + Text = ("Resize") + } + { lblSize Label + MoveScaled(14,14,34,5) + Font = Font["Bold,+5"] + Foreground = Color.TextBackground + AutoResize = True + } + } +} diff --git a/examples/examples/Image/PhotoTouch/.src/FScissors.class b/examples/examples/Image/PhotoTouch/.src/FScissors.class index fb5973489..d95175c13 100644 --- a/examples/examples/Image/PhotoTouch/.src/FScissors.class +++ b/examples/examples/Image/PhotoTouch/.src/FScissors.class @@ -14,7 +14,7 @@ Private $hRect As Rect Private btnCut As CButton -Private Sub Form_Resize() +Public Sub Form_Resize() $aScissors[S_NW].Move(0, 0, HANDLE_SIZE, HANDLE_SIZE) $aScissors[S_NE].Move(Me.W - HANDLE_SIZE, 0, HANDLE_SIZE, HANDLE_SIZE) @@ -25,7 +25,7 @@ Private Sub Form_Resize() $aScissors[S_W].Move(0, HANDLE_SIZE, HANDLE_SIZE, Me.H - HANDLE_SIZE * 2) $aScissors[S_E].Move(Me.W - HANDLE_SIZE, HANDLE_SIZE, HANDLE_SIZE, Me.H - HANDLE_SIZE * 2) - btnCut.Move(Me.W - 64 - Desktop.Scale * 3, Desktop.Scale * 3) + btnCut.Move(Me.W - btnCut.W - Desktop.Scale * 3, Desktop.Scale * 3) End @@ -49,11 +49,11 @@ Public Sub Form_Open() Next btnCut = New CButton(Me) As "btnCut" - btnCut.Resize(64, 64) + btnCut.Resize(48, 48) btnCut.Image = Image.Load("scissors.png") Me.Move(FMain.ClientW \ 4, FMain.ClientH \ 4, FMain.ClientW \ 2, FMain.ClientH \ 2) - Form_Resize + 'Form_Resize End @@ -69,8 +69,8 @@ Public Sub Panel_MouseMove() Dim X, Y As Integer Dim iTag As Integer = Last.Tag - Dim MIN_HEIGHT As Integer = 64 + Desktop.Scale * 6 - Dim MIN_WIDTH As Integer = 64 + Desktop.Scale * 6 + Dim MIN_HEIGHT As Integer = btnCut.W + Desktop.Scale * 6 + Dim MIN_WIDTH As Integer = btnCut.H + Desktop.Scale * 6 Select Case Last.Tag @@ -124,7 +124,7 @@ Public Sub Panel_MouseMove() End Select - Form_Resize + 'Form_Resize End diff --git a/examples/examples/Image/PhotoTouch/.startup b/examples/examples/Image/PhotoTouch/.startup index b7f2100d3..eb0c99877 100644 --- a/examples/examples/Image/PhotoTouch/.startup +++ b/examples/examples/Image/PhotoTouch/.startup @@ -8,5 +8,6 @@ gb.image gb.qt4 gb.form gb.desktop +gb.settings gb.image.effect diff --git a/examples/examples/Image/PhotoTouch/control.png b/examples/examples/Image/PhotoTouch/balance.png similarity index 100% rename from examples/examples/Image/PhotoTouch/control.png rename to examples/examples/Image/PhotoTouch/balance.png diff --git a/examples/examples/Image/PhotoTouch/blur.png b/examples/examples/Image/PhotoTouch/blur.png new file mode 100644 index 0000000000000000000000000000000000000000..95edf31cf5aaad913df37f88fe50959762fbc502 GIT binary patch literal 1924 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 literal 0 HcmV?d00001 diff --git a/examples/examples/Image/PhotoTouch/invert.png b/examples/examples/Image/PhotoTouch/invert.png new file mode 100644 index 0000000000000000000000000000000000000000..3bc3844aa98e89896ddcfc9202ce270155f5789f GIT binary patch literal 3064 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 Qr2qf`07*qoM6N<$f|&U!xc~qF literal 0 HcmV?d00001 diff --git a/examples/examples/Image/PhotoTouch/vflip.png b/examples/examples/Image/PhotoTouch/vflip.png new file mode 100644 index 0000000000000000000000000000000000000000..9a6720bd57edefcc0da7a4e095fd00bcb5109c37 GIT binary patch literal 1434 zcmV;L1!ek)P)Px)R7pfZRCwC$n@?zycNoW?U(z%rmWV=?N(;*zLFkGFA?PXy1zA1m2FVWFa#L^{ zJxnmr4aAdSgV59J#m-BYUFr_49&8VGV52M(X$OU^O3{{8sTAAA5?k}xCGV(R-e2C> zH~(rMcrN+-e7qB(NRW6M|C1R1oqb|{NdaRpVzKly-HnO z9WIxPL_)VN@(eg!Yw*W`Wiz7Q-d>bahzKHrQi|T*UY!Wb!0}pv?*h_hB++Q}Kk$tn zjYf4M`~!Sg?eL!fnS9Y_vst>kyG`K@@9yp?|7I z@XpRomX?-uB76s^O2NBwd-uGyu&_Wd7<^-R!-K&f3kwT65e5KPx#2y)uvtWNb91z| zwr(2U@YdE==H}*fA`Anbsz_?4r>F7z{kFjy?)Uqdo}R935(Vr7Ce0$4n3$lcsmXSD z!<(9#n3$NTOcIrY|HJH?lgT8zcI_$|yy3fd?O`0X_Sp^Z*CjPKZ{B3bjvXb3 zH@u;tfsv7sLP^v+cELM=akFn492~^$c9#v_aJSpd;NYN6gmJ)W*A6eQUAb}vr_)(> zc*C7eC;k2XIuX9MLx5DiPmagquVr+Va-|gUc-%~Y-wN?53j!>QNW=Qa?%%&Jmo8lr zz>FJS!2M=z1YFR1e+w2wa7n`(DC{*+>8w!Q6 z!Tv17=dhr`cnw$O#_bT`8xcv@AbeUxzTLC{N~u{9iHOLH8iIczBA@4C-}DtAN~voi za#%$AMC9)(h0cn|JrRkCNKh&DiGsrLZJK10(sdz_2$eOm*z z%jIHVV8HCoaL10@j%itZXlMwJ$5SzQkH^FC@Nmh?;@ZZ@ty{P7`Fv%E_xXH`jg6JQ zF_IHO+Zs!yQZzO;mJPnKv5{0NRi4(^IuW$Z(W$8^T3T944&Tz!!qn7Md7Go_M9|I# z%*@OX2n0$79|#1PnVHeSj{*&)-iy0|Yi1G5&(G7|-fla5dwV!o|=&)5{cI`Neib&o&twzsuBSl03MkUUB7-E zuh)y$>*dCc8#?$$z=4`9$Gp{trq+p2?3qEs?ro*BgH}(C8a7h$q^1HQXp^XlBsCQh o;q5#;y+H`$`22&MSM2!wzoNhzDMtIFwEzGB07*qoM6N<$f-feuBme*a literal 0 HcmV?d00001