Что нового

Разработка GUI для проекта по оптимизации изображений без потери качества

lorents

Чайник
Сообщения
82
Репутация
1
Добрый день!
У меня есть проект Image Catalyst, суть проект в оптимизации картинок без потери качества

технология описана здесь (статья моя)
http://habrahabr.ru/blogs/client_side_optimization/119009/

Хотелось бы сделать GUI для проект, но знаний пока таких нету, решил обратится, может у кого есть желание мне помочь? Сам проект будет бесплатными, конкурентов мало, мой алгоритм оптимизации наголову превосходит. Из GUI конкурентов двое:
PNGOutWin (платный);
PNGGauntlet.

Основные требования к приложению:
1. запретить одновременную работу более одной копии проекта;
2. сделать многопоточность при оптимизации PNG изображений;

Этапы оптимизации изображений
1. изображение копируется во временную папку
2. запускаем алгоритм оптимизации изображений (более подробно я напишу позже);
3. если размер оптимизированного изображения меньше оригинального, то (в зависимости от настроек приложения):
* заменяем оригинальное изображение на оптимизированное;
* сохраняем оптимизированное/оригинальное изображение в указанную папку.
4. добавляем сведения о проделанной работе в объект TreeList.



Работа с папками
1. при добавлении папок с изображения делаем поиск изображений (в зависимости от настроек приложения):
* поиск изображений ведется только в указанной папке;
* поиск изображений ведется в казанной папке, включая вложенные подпапки.
2. полученная структура отображается в объекте TreeList.
Пример 1:
Пользователь указал оптимизировать изображения в папке Dir1, включая вложенные папки, в папке Dir1 есть папки Dir2 и Dir3. Следовательно, в объекте TreeList указываем папку Dir1 и подпапки Dir2 и Dir3
3. если пользователь указал сохранять оптимизированные изображения в другой папке, то воссоздается и вся структура папок.
Пример 2:
Продолжение примера 1. Допустим, пользователь указал сохранять оптимизированные изображения в папке Images. Следовательно, в папке Images создается папка Dir1 и подпапки Dir2 и Dir3 и в них помещаются оптимизированные изображения.
Если в папке Images уже существует папка Dir1, то мы создаем папку Dir1 (1), и так далее.
При совпадении имен файлов действуем в том же направлении.

Меню проекта
File
* File add
* Folder add
* -------------
* Exit
Actions
* Start
* Stop
Tools
* Options
Help
* Help
* Check for Update
* About

File add
Открывается диалоговое окно выбора файлов с возможностью выбора нескольких файлов



В строке тип файла указывается
* File PNG (*.png)
* File JPEG (*.jpg, *.jpeg, *.jpe)
* All supported File (*.png, *.jpg, *.jpeg, *.jpe)

Folder add
Открывается диалоговое окно выбора папки



Exit
Выход из приложения

Start
Запускается процесс оптимизации изображения, примет все пункты меню блокируются за исключением Pause и Stop

Stop
Процесс оптимизации изображений отключается, при этом:
* новые файлы не отправляются в работу;
* принудительно завершаем запущенные процессы;
* чистим временную папку.

Options
Три основные вкладки (более подробно я напишу позже):
* настройки самого приложения;
* настройки оптимизации PNG;
* настройки оптимизации JPEG.

Help
Запускается справка приложения

Check for Update
Проверяется наличие обновления

About
О приложении (версия, сайт, авторы и т.д.)
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
369
Re: Image Catalyst

lorents [?]
Основные требования к приложению:
1. запретить одновременную работу более одной копии проекта;
2. сделать многопоточность при оптимизации PNG изображений;
AutoIt онопоточен по определению

А вот все остальное вполне осуществимо, если интересует могу начать.
 
Автор
L

lorents

Чайник
Сообщения
82
Репутация
1
Re: Image Catalyst

Redline благодарю, что отозвались.

смотрите, многопоточность, очень важная функция, без нее нет смысла реализовывать проект
смотрел вот эту тему, может поможет.

Смотрите, оптимизация изображений происходит по специальному алгоритму (грубо говоря эта цепочка приложений). Суть задачи в том, чтобы я мог последовательно запустить допустим 4 алгоритма с изображениями подряд и ждал их завершения, как только один поток завершил работу, запускаем другой и т.д. Выходит у нас 4 независимых потока.

Такой вопрос, а вы не хотели бы сейчас помочь кое-что сделать для текущей версии?
нужно, написать несколько скриптов, они не сложные.
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
369
Re: Image Catalyst

lorents
Да можно будет запустить программ-обработчиков и ждать ответа от них.

Такой вопрос, а вы не хотели бы сейчас помочь кое-что сделать для текущей версии?
нужно, написать несколько скриптов, они не сложные.
Я уже накидал GUI с менюшками и листом, сейчас буду навешивать алгоритмы на пункты меню. Попозже выложу примерчик.

Или вы что-то другое имели ввиду под помощью? :smile:
 
Автор
L

lorents

Чайник
Сообщения
82
Репутация
1
Re: Image Catalyst

Или вы что-то другое имели ввиду под помощью
А вы не хотите стать постоянным участником?

Жду с нетерпением GUI пример
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
369
Re: Image Catalyst

lorents [?]
А вы не хотите стать постоянным участником?
Могу заниматься в свободное время

Вот примерно так я это вижу:
Код:
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <StaticConstants.au3>
#include <ListviewConstants.au3>
#include <Array.au3>
#include <Misc.au3>
Opt('GUICloseOnESC', 0) ; не закрывать окно по Esc
HotKeySet('+^{SPACE}', '_pause')
Global $sProjectName = 'Image Catalyst', $fPause = False, $sEmail = '[email protected]', $sSite = 'www.autoit-script.ru'
; проверка на повторный запуск ----------------------------------------
If Not _Singleton($sProjectName, 1) Then
	MsgBox(262192, 'Error', 'The program is already running!')
	Exit
EndIf
AutoItWinSetTitle($sProjectName)

$hGUI = GUICreate($sProjectName, 640, 480)
; Меню -------------------------------------------------------------
$hHeader_MenuFile = GUICtrlCreateMenu('File')
$hMenuFile_FileAdd = GUICtrlCreateMenuItem('File add', $hHeader_MenuFile)
$hMenuFile_FolderAdd = GUICtrlCreateMenuItem('Folder add', $hHeader_MenuFile)
GUICtrlCreateMenuItem('', $hHeader_MenuFile)
$hMenuFile_Exit = GUICtrlCreateMenuItem('Exit', $hHeader_MenuFile)

$hHeader_MenuActions = GUICtrlCreateMenu('Actions')
GUICtrlSetState(-1, $GUI_DISABLE) ; будет недоступно пока нет выбраных файлов
$hMenuActions_Start = GUICtrlCreateMenuItem('Start', $hHeader_MenuActions)
$hMenuActions_Stop = GUICtrlCreateMenuItem('Stop', $hHeader_MenuActions)
GUICtrlSetState(-1, $GUI_DISABLE) ; будет недоступно пока не начата обработка

$hHeader_MenuTools = GUICtrlCreateMenu('Tools')
$hMenuTools_Options = GUICtrlCreateMenuItem('Options', $hHeader_MenuTools)

$hHeader_MenuHelp = GUICtrlCreateMenu('Help')
$hMenuHelp_Help = GUICtrlCreateMenuItem('Help', $hHeader_MenuHelp)
$hMenuHelp_Update = GUICtrlCreateMenuItem('Check for updates', $hHeader_MenuHelp)
GUICtrlCreateMenuItem('', $hHeader_MenuHelp)
$hMenuHelp_About = GUICtrlCreateMenuItem('About', $hHeader_MenuHelp)
; Лист -------------------------------------------------------------
$hList = GUICtrlCreateListView('', 5, 15, 630, 460, BitOR($LVS_SHOWSELALWAYS, $LVS_REPORT), BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))

GUISetState(@SW_SHOW)

While 1
	$hMsg = GUIGetMsg()
	Select
		Case $hMsg = -3 ; закрытие программы по ALT-F4
			Exit
		Case $hMsg = $hMenuFile_FileAdd ; добавить файл(ы)
			$sFiles = FileOpenDialog('Select file(s) to convert', @DesktopDir, 'File PNG (*.png)|File JPEG (*.jpg;*.jpeg;*.jpe)|All supported File (*.png;*.jpg;*.jpeg;*.jpe)', 7)
			If Not @error Then
				$aFiles = StringSplit($sFiles, '|', 2) ; массив с файлами
				_ArrayDisplay($aFiles)
				GUICtrlSetState($hHeader_MenuActions, $GUI_ENABLE) ; разблокируем меню действий
				GUICtrlSetState($hMenuActions_Start, $GUI_ENABLE) ; разблокируем Start
			EndIf
		Case $hMsg = $hMenuFile_FolderAdd ; добавить папку
			$sFolder = FileSelectFolder('Select folder to convert', @DesktopDir, 2)
			If Not @error Then
				ConsoleWrite($sFolder & @CRLF) ; строка с папкой
				GUICtrlSetState($hHeader_MenuActions, $GUI_ENABLE) ; разблокируем меню действий
				GUICtrlSetState($hMenuActions_Start, $GUI_ENABLE) ; разблокируем Start
			EndIf
		Case $hMsg = $hMenuFile_Exit ; закрытие через Exit
			Exit
		Case $hMsg = $hMenuActions_Start ; запуск обработки
			GUICtrlSetData($hMenuActions_Start, 'Pause') ; смена названия Start на Pause
			GUICtrlSetState($hMenuActions_Stop, $GUI_ENABLE) ; разблокируем Stop
			GUICtrlSetState($hHeader_MenuFile, $GUI_DISABLE) ; отключение лишних меню
			GUICtrlSetState($hHeader_MenuTools, $GUI_DISABLE)
			GUICtrlSetState($hHeader_MenuHelp, $GUI_DISABLE)
			Opt('GUIOnEventMode', 1)
			GUICtrlSetOnEvent($hMenuActions_Stop, '_terminate')
			GUICtrlSetOnEvent($hMenuActions_Start, '_pause')
			; --------------------------------------------------
			; ------------------- обработка --------------------
			; --------------------------------------------------
			For $i = 0 To 10
				ConsoleWrite('main ' & $i & @CRLF)
				Sleep(1000)
			Next

			Opt('GUIOnEventMode', 0)
			GUICtrlSetData($hMenuActions_Start, 'Start') ; восстановление прежнего состояния меню
			GUICtrlSetState($hHeader_MenuActions, $GUI_DISABLE)
			GUICtrlSetState($hMenuActions_Stop, $GUI_DISABLE)
			GUICtrlSetState($hHeader_MenuTools, $GUI_DISABLE)
			GUICtrlSetState($hHeader_MenuFile, $GUI_ENABLE)
			GUICtrlSetState($hHeader_MenuTools, $GUI_ENABLE)
			GUICtrlSetState($hHeader_MenuHelp, $GUI_ENABLE)
		Case $hMsg = $hMenuTools_Options ; окно опций
			GUISetState(@SW_DISABLE, $hGUI)
			$hGUI_options = GUICreate('Options', 400, 200, -1, -1, $GUI_SS_DEFAULT_GUI, $WS_EX_TOOLWINDOW, $hGUI)
			$hTab = GUICtrlCreateTab(5, 5, 390, 190)
				$hTab_app_options = GUICtrlCreateTabItem('Application options') ; закладка общих опций
					GUICtrlCreateCheckbox('123', 10, 30)
					GUICtrlCreateCheckbox('456', 10, 50)
					GUICtrlCreateCheckbox('789', 10, 70)
				$hTab_PNG_options = GUICtrlCreateTabItem('PNG options') ; закладка опций PNG
					GUICtrlCreateCheckbox('aaa', 10, 30)
					GUICtrlCreateCheckbox('bbb', 10, 50)
					GUICtrlCreateCheckbox('ccc', 10, 70)
				$hTab_JPEG_options = GUICtrlCreateTabItem('JPEG options') ; закладка опций JPEG
					GUICtrlCreateCheckbox('ёёё', 10, 30)
					GUICtrlCreateCheckbox('фффф', 10, 50)
					GUICtrlCreateCheckbox('ччч', 10, 70)
				GUICtrlCreateTabItem('')
			GUISetState(@SW_SHOW, $hGUI_options)
			While 1
				$hMsg_options = GUIGetMsg()
				Select
					Case $hMsg_options = -3
						ExitLoop
				EndSelect
			WEnd
			GUIDelete($hGUI_options)
			GUISetState(@SW_ENABLE, $hGUI)
		Case $hMsg = $hMenuHelp_Help ; запуск файла помощи
			ShellExecute(@ScriptDir & '\UDFs3.chm')
		Case $hMsg = $hMenuHelp_Update
			; здесь нужно думать откуда/как качать и как проверять номер версии, время и т.п.
		Case $hMsg = $hMenuHelp_About ; окно О программе (из заготовки :-) )
			GUISetState(@SW_DISABLE, $hGUI)
			$hGui_about = GUICreate('About ' & $sProjectName, 300, 120, -1, -1, $GUI_SS_DEFAULT_GUI, $WS_EX_TOOLWINDOW, $hGUI)
			$hMail = GUICtrlCreateLabel($sEmail, 212, 102, 85, 15, $SS_RIGHT)
			GUICtrlSetFont(-1, -1, 400, 4)
			GUICtrlSetColor(-1, 0x000FF)
			GUICtrlSetCursor(-1, 0)
			$hSite = GUICtrlCreateLabel($sSite, 10, 80, 280, 15, $SS_CENTER)
			GUICtrlSetFont(-1, -1, 400, 4)
			GUICtrlSetColor(-1, 0x000FF)
			GUICtrlSetCursor(-1, 0)
			$hDrag = GUICtrlCreatePic('', 0, 0, 300, 120, -1, $GUI_WS_EX_PARENTDRAG)
			$hProject = GUICtrlCreateLabel($sProjectName, 35, 42, 230, 25, $SS_CENTER)
			GUICtrlSetFont(-1, 11, 800)
			GUICtrlCreateGroup('', 25, 20, 250, 58)
			$hCopy = GUICtrlCreateLabel('Copyright © ' & @YEAR & ' lorents', 5, 102, 140, 15, $SS_LEFT)
			GUISetState(@SW_SHOW)
			While 1
				$hMsg_about = GUIGetMsg()
				Select
					Case $hMsg_about = -3
						ExitLoop
					Case $hMsg_about = $hMail
						ShellExecute('mailto:' & $sEmail)
					Case $hMsg_about = $hSite
						ShellExecute($sSite)
				EndSelect
			WEnd
			GUIDelete($hGui_about)
			GUISetState(@SW_ENABLE, $hGUI)
	EndSelect
WEnd

Func _pause() ; функция паузы
	$fPause = Not $fPause
	If $fPause Then
		GUICtrlSetData($hMenuActions_Start, 'Unpause')
		AdlibRegister('_checkPause', 250)
	EndIf
	While $fPause
		Sleep(500)
		ConsoleWrite(@SEC & ':' & @MSEC & @CRLF)
	WEnd
	GUICtrlSetData($hMenuActions_Start, 'Pause')
	AdlibUnRegister('_checkPause')
EndFunc

Func _terminate()
	Sleep(100)
EndFunc

Func _checkPause() ; функция проверки не была ли отжата пауза
	Opt('GUIOnEventMode', 0)
	$hMsgTemp = GUIGetMsg()
	If $hMsgTemp = $hMenuActions_Start Then	$fPause = False
	Opt('GUIOnEventMode', 1)
EndFunc
Как и предполагал - возникли проблемы со снятием с паузы - проще всего это реализовать через горячие клавиши. Но после танцев с бубном удалось обойтись без клавиатуры.

Позже добавлю работу с листом.
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
369
Re: Image Catalyst

Вот с рабочим листом - в него пишутся полные пути файлов, которые добавлены через добавление файлов или папок.
Создал общий массив куда копируются пути всех файлов, наверняка основная работа будет с ним.

По поводу TreeView не совсем ясно его предназначение.
Сделал простой TreeView в котором слева отображается имя добавленного файла, а если добавлена папка, то отображается имя папки без полного пути и добавляется ветвление, но только на один уровень. Делать полное ветвление дюже сложно, а добавлять событие при клике на него или еще что-то будет еще сложнее. Поэтому предлагаю от него отказаться совсем.

По поводу действий при совпадении названий.
Правильно ли я понял:
Если копируется выбранная нами папка, то при условии присутствия в папке-приемнике такой же папки мы создаем копию?
Если с такими же условиями копируется выбранный нами файл, то создаем его копию?
Если все так, то это реализуется элементарно.

Дело за малым. Мне нужно знать как нужно передавать в утилиту файлы (в каком виде, по сколько штук/папок и т.д.). Временную папку создать и удалить так же легко, как и прервать весь процесс.

В общем разбирайтесь с кодом, а во вторник (может понедельник) продолжим ;)
Код:
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <StaticConstants.au3>
#include <ListviewConstants.au3>
#include <TreeViewConstants.au3>
#include <Array.au3>
#include <Misc.au3>
Opt('GUICloseOnESC', 0) ; не закрывать окно по Esc
HotKeySet('+^{SPACE}', '_pause')
Global $sProjectName = 'Image Catalyst', $fPause = False, $sEmail = '[email protected]', $sSite = 'www.autoit-script.ru', $aAllFiles[1][2], $aTree[1]
; проверка на повторный запуск ----------------------------------------
If Not _Singleton($sProjectName, 1) Then
	MsgBox(262192, 'Error', 'The program is already running!')
	Exit
EndIf
AutoItWinSetTitle($sProjectName)

$hGUI = GUICreate($sProjectName, 640, 880, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX, $WS_MAXIMIZEBOX))
; Меню -------------------------------------------------------------
$hHeader_MenuFile = GUICtrlCreateMenu('File')
$hMenuFile_FileAdd = GUICtrlCreateMenuItem('File add', $hHeader_MenuFile)
$hMenuFile_FolderAdd = GUICtrlCreateMenuItem('Folder add', $hHeader_MenuFile)
GUICtrlCreateMenuItem('', $hHeader_MenuFile)
$hMenuFile_Exit = GUICtrlCreateMenuItem('Exit', $hHeader_MenuFile)

$hHeader_MenuActions = GUICtrlCreateMenu('Actions')
GUICtrlSetState(-1, $GUI_DISABLE) ; будет недоступно пока нет выбраных файлов
$hMenuActions_Start = GUICtrlCreateMenuItem('Start', $hHeader_MenuActions)
$hMenuActions_Stop = GUICtrlCreateMenuItem('Stop', $hHeader_MenuActions)
GUICtrlSetState(-1, $GUI_DISABLE) ; будет недоступно пока не начата обработка

$hHeader_MenuTools = GUICtrlCreateMenu('Tools')
$hMenuTools_Options = GUICtrlCreateMenuItem('Options', $hHeader_MenuTools)

$hHeader_MenuHelp = GUICtrlCreateMenu('Help')
$hMenuHelp_Help = GUICtrlCreateMenuItem('Help', $hHeader_MenuHelp)
$hMenuHelp_Update = GUICtrlCreateMenuItem('Check for updates', $hHeader_MenuHelp)
GUICtrlCreateMenuItem('', $hHeader_MenuHelp)
$hMenuHelp_About = GUICtrlCreateMenuItem('About', $hHeader_MenuHelp)
; Лист -------------------------------------------------------------
$hList = GUICtrlCreateListView('path', 5, 0, 630, 460, BitOR($LVS_SHOWSELALWAYS, $LVS_REPORT), BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))
_GUICtrlListView_SetColumnWidth($hList, 0, 610)
; дерево -----------------------------------------------------------
$hTree = GUICtrlCreateTreeView(5, 470, 630, 380, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS), $WS_EX_CLIENTEDGE)
GUISetState(@SW_SHOW)

While 1
	$hMsg = GUIGetMsg()
	Select
		Case $hMsg = -3 ; закрытие программы по ALT-F4
			Exit
		Case $hMsg = $hMenuFile_FileAdd ; добавить файл(ы)
			$sFiles = FileOpenDialog('Select file(s) to convert', @DesktopDir, 'File PNG (*.png)|File JPEG (*.jpg;*.jpeg;*.jpe)|All supported File (*.png;*.jpg;*.jpeg;*.jpe)', 7)
			If Not @error Then
				$aFiles = StringSplit($sFiles, '|', 2) ; массив с файлами
				If UBound($aFiles) = 1 Then ; добавлен один файл
					ReDim $aAllFiles[UBound($aAllFiles) + 1][2]
					$aAllFiles[UBound($aAllFiles) - 2][0] = StringRegExpReplace($aFiles[0], '\\[^\\]*$', '')
					$aAllFiles[UBound($aAllFiles) - 2][1] = StringRegExpReplace($aFiles[0], '^.*\\', '')
					GUICtrlCreateListViewItem($aFiles[0], $hList) ; строка листа
					GUICtrlCreateTreeViewItem($aFiles[0], $hTree) ; ветка дерева
				Else ; добавлены несколько файлов
					$iLast = UBound($aAllFiles) - 2
					ReDim $aAllFiles[UBound($aAllFiles) - 1 + UBound($aFiles)][2]
					For $i = 1 To UBound($aFiles) - 1
						$aAllFiles[$iLast + $i][0] = $aFiles[0]
						$aAllFiles[$iLast + $i][1] = $aFiles[$i]
						GUICtrlCreateListViewItem($aFiles[0] & '\' & $aFiles[$i], $hList) ; строка листа
						GUICtrlCreateTreeViewItem($aFiles[0] & '\' & $aFiles[$i], $hTree) ; ветка дерева
					Next
				EndIf
				GUICtrlSetState($hHeader_MenuActions, $GUI_ENABLE) ; разблокируем меню действий
				GUICtrlSetState($hMenuActions_Start, $GUI_ENABLE) ; разблокируем Start
				_ArrayDisplay($aAllFiles)
			EndIf
		Case $hMsg = $hMenuFile_FolderAdd ; добавить папку
			$sFolder = FileSelectFolder('Select folder to convert', @DesktopDir, 2)
			If Not @error Then
;~ 				$sFilter = '*.png' ; фильтр для поиска
;~ 				$sFilter = '*.jpg;*.jpeg;*.jpe'
				$sFilter = '*.png;*.jpg;*.jpeg;*.jpe'
				$iSubfolderFlag = 1 ; флаг поиска в поддиректориях
				$aFiles = _FileSearch($sFolder, $sFilter, $iSubfolderFlag)
				If Not @error And $aFiles[0] > 0 Then ; поиск произведен и найден хоть один файл
					$iLast = UBound($aAllFiles) - 2
					$sLastFolder = StringRegExpReplace($sFolder, '^.*\\', '')
					ReDim $aAllFiles[UBound($aAllFiles) - 1 + UBound($aFiles)][2]
					$aTree[UBound($aTree) - 1] = GUICtrlCreateTreeViewItem($sLastFolder, $hTree) ; ответвление дерева
					If $iSubfolderFlag Then
						For $i = 1 To UBound($aFiles) - 1
							$sSubFolder = StringReplace($aFiles[$i], $sFolder & '\', '')
							$sFilePass = StringReplace($aFiles[$i], $sFolder & '\', '')
							$aAllFiles[$iLast + $i][0] = $sFolder
							$aAllFiles[$iLast + $i][1] = $sFilePass
							GUICtrlCreateListViewItem($aFiles[$i], $hList) ; строка таблицы
							GUICtrlCreateTreeViewItem($sSubFolder, $aTree[UBound($aTree) - 1]) ; ветка дерева
						Next
					Else
						For $i = 1 To UBound($aFiles) - 1
							$sSubFolder = StringReplace($aFiles[$i], $sFolder & '\', '')
							$sFilePass = StringReplace($aFiles[$i], $sFolder & '\', '')
							$aAllFiles[$iLast + $i][0] = $sFolder
							$aAllFiles[$iLast + $i][1] = $sFilePass
							GUICtrlCreateListViewItem($sFolder & '\' & $aFiles[$i], $hList) ; строка таблицы
							GUICtrlCreateTreeViewItem($sSubFolder, $aTree[UBound($aTree) - 1]) ; ветка дерева
						Next
					EndIf
					ReDim $aTree[UBound($aTree) + 1]
					GUICtrlSetState($hHeader_MenuActions, $GUI_ENABLE) ; разблокируем меню действий
					GUICtrlSetState($hMenuActions_Start, $GUI_ENABLE) ; разблокируем Start
					_ArrayDisplay($aAllFiles)
				EndIf
			EndIf
		Case $hMsg = $hMenuFile_Exit ; закрытие через Exit
			Exit
		Case $hMsg = $hMenuActions_Start ; запуск обработки
			GUICtrlSetData($hMenuActions_Start, 'Pause') ; смена названия Start на Pause
			GUICtrlSetState($hMenuActions_Stop, $GUI_ENABLE) ; разблокируем Stop
			GUICtrlSetState($hHeader_MenuFile, $GUI_DISABLE) ; отключение лишних меню
			GUICtrlSetState($hHeader_MenuTools, $GUI_DISABLE)
			GUICtrlSetState($hHeader_MenuHelp, $GUI_DISABLE)
			Opt('GUIOnEventMode', 1)
			GUICtrlSetOnEvent($hMenuActions_Stop, '_terminate')
			GUICtrlSetOnEvent($hMenuActions_Start, '_pause')
			; --------------------------------------------------
			; ------------------- обработка --------------------
			; --------------------------------------------------
			For $i = 0 To 10
				ConsoleWrite('main ' & $i & @CRLF)
				Sleep(1000)
			Next
			Opt('GUIOnEventMode', 0)
			GUICtrlSetData($hMenuActions_Start, 'Start') ; восстановление прежнего состояния меню
			GUICtrlSetState($hHeader_MenuActions, $GUI_DISABLE)
			GUICtrlSetState($hMenuActions_Stop, $GUI_DISABLE)
			GUICtrlSetState($hHeader_MenuTools, $GUI_DISABLE)
			GUICtrlSetState($hHeader_MenuFile, $GUI_ENABLE)
			GUICtrlSetState($hHeader_MenuTools, $GUI_ENABLE)
			GUICtrlSetState($hHeader_MenuHelp, $GUI_ENABLE)
		Case $hMsg = $hMenuTools_Options ; окно опций
			GUISetState(@SW_DISABLE, $hGUI)
			$hGUI_options = GUICreate('Options', 400, 200, -1, -1, $GUI_SS_DEFAULT_GUI, $WS_EX_TOOLWINDOW, $hGUI)
			$hTab = GUICtrlCreateTab(5, 5, 390, 190)
			$hTab_app_options = GUICtrlCreateTabItem('Application options') ; закладка общих опций
			GUICtrlCreateCheckbox('123', 10, 30)
			GUICtrlCreateCheckbox('456', 10, 50)
			GUICtrlCreateCheckbox('789', 10, 70)
			$hTab_PNG_options = GUICtrlCreateTabItem('PNG options') ; закладка опций PNG
			GUICtrlCreateCheckbox('aaa', 10, 30)
			GUICtrlCreateCheckbox('bbb', 10, 50)
			GUICtrlCreateCheckbox('ccc', 10, 70)
			$hTab_JPEG_options = GUICtrlCreateTabItem('JPEG options') ; закладка опций JPEG
			GUICtrlCreateCheckbox('ёёё', 10, 30)
			GUICtrlCreateCheckbox('фффф', 10, 50)
			GUICtrlCreateCheckbox('ччч', 10, 70)
			GUICtrlCreateTabItem('')
			GUISetState(@SW_SHOW, $hGUI_options)
			While 1
				$hMsg_options = GUIGetMsg()
				Select
					Case $hMsg_options = -3
						ExitLoop
				EndSelect
			WEnd
			GUIDelete($hGUI_options)
			GUISetState(@SW_ENABLE, $hGUI)
		Case $hMsg = $hMenuHelp_Help ; запуск файла помощи
			ShellExecute(@ScriptDir & '\UDFs3.chm')
		Case $hMsg = $hMenuHelp_Update
			; здесь нужно думать откуда/как качать и как проверять номер версии, время и т.п.
		Case $hMsg = $hMenuHelp_About ; окно 'О программе' из заготовки :-)
			GUISetState(@SW_DISABLE, $hGUI)
			$hGui_about = GUICreate('About ' & $sProjectName, 300, 120, -1, -1, $GUI_SS_DEFAULT_GUI, $WS_EX_TOOLWINDOW, $hGUI)
			$hMail = GUICtrlCreateLabel($sEmail, 212, 102, 85, 15, $SS_RIGHT)
			GUICtrlSetFont(-1, -1, 400, 4)
			GUICtrlSetColor(-1, 0x000FF)
			GUICtrlSetCursor(-1, 0)
			$hSite = GUICtrlCreateLabel($sSite, 10, 80, 280, 15, $SS_CENTER)
			GUICtrlSetFont(-1, -1, 400, 4)
			GUICtrlSetColor(-1, 0x000FF)
			GUICtrlSetCursor(-1, 0)
			$hDrag = GUICtrlCreatePic('', 0, 0, 300, 120, -1, $GUI_WS_EX_PARENTDRAG)
			$hProject = GUICtrlCreateLabel($sProjectName, 35, 42, 230, 25, $SS_CENTER)
			GUICtrlSetFont(-1, 11, 800)
			GUICtrlCreateGroup('', 25, 20, 250, 58)
			$hCopy = GUICtrlCreateLabel('Copyright © ' & @YEAR & ' lorents', 5, 102, 140, 15, $SS_LEFT)
			GUISetState(@SW_SHOW)
			While 1
				$hMsg_about = GUIGetMsg()
				Select
					Case $hMsg_about = -3
						ExitLoop
					Case $hMsg_about = $hMail
						ShellExecute('mailto:' & $sEmail)
					Case $hMsg_about = $hSite
						ShellExecute($sSite)
				EndSelect
			WEnd
			GUIDelete($hGui_about)
			GUISetState(@SW_ENABLE, $hGUI)
	EndSelect
WEnd

Func _pause() ; функция паузы
	$fPause = Not $fPause
	If $fPause Then
		GUICtrlSetData($hMenuActions_Start, 'Unpause')
		AdlibRegister('_checkPause', 250)
	EndIf
	While $fPause
		Sleep(500)
		ConsoleWrite(@SEC & ':' & @MSEC & @CRLF)
	WEnd
	GUICtrlSetData($hMenuActions_Start, 'Pause')
	AdlibUnRegister('_checkPause')
EndFunc   ;==>_pause

Func _terminate()
	Sleep(100)
EndFunc   ;==>_terminate

Func _checkPause() ; функция проверки не была ли отжата пауза
	Opt('GUIOnEventMode', 0)
	$hMsgTemp = GUIGetMsg()
	If $hMsgTemp = $hMenuActions_Start Then $fPause = False
	Opt('GUIOnEventMode', 1)
EndFunc   ;==>_checkPause

Func _FileSearch($sPath, $sFileMask, $iSubDir = 1)
	Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib

	If $iSubDir = 1 Then
		$sAttrib = ' /S /B /A'
	Else
		$sAttrib = ' /B /A'
	EndIf

	$sOut = StringToBinary('0' & @CRLF, 2)
	$aMasks = StringSplit($sFileMask, ';')

	For $i = 1 To $aMasks[0]
		$hDir = Run(@ComSpec & ' /U /C DIR "' & $sPath & '\' & $aMasks[$i] & '"' & $sAttrib, @SystemDir, @SW_HIDE, 6)

		While 1
			$sRead = StdoutRead($hDir, False, True)

			If @error Then
				ExitLoop
			EndIf

			If $sRead <> '' Then
				$sOut &= $sRead
			EndIf
		WEnd
	Next

	$aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)

	If @error Then
		Return SetError(1)
	EndIf

	$aOut[0] = UBound($aOut) - 1
	Return $aOut
EndFunc   ;==>_FileSearch
 
Автор
L

lorents

Чайник
Сообщения
82
Репутация
1
Re: Image Catalyst

Redline отличная работа :smile:

Хочу сразу сказать, на счет алгоритмов оптимизации они сейчас не нужны.

и так продолжим:
1. TreeList нужен для того, чтобы пользователь мог видеть папку которую он добавил, и мы ищем изображения не только в папке которую он указал, но и вложенные папки, посмотрите на картинку добавления папок



Картинку TreeList я привел как пример.
Допустим у пользователя есть папка C:\Downloads\Joomla и там есть вложенные папки. Пользователь добавляет папку Joomla с вложенными папками. В TreeList мы должны отобразить папку Joomla с изображениями а так же вложенные папки с изображениями.

Столбцы TreeList:
- File Name (отображаем как раз папки и изображения);
- Original Size (оригинальный размер изображений, в кб, округляем до сотых);
- New Size (оптимизированный размер изображений, в кб, округляем до сотых);
- Savings (разница между оптимизированным и оригинальным размерами, в кб, округляем до сотых);
- % Savings (считаем так, (1-New Size/Original Size)*100, округляем до сотых);
- Path (путь сохранения изображения, здесь два варианта: заменяем оригинальные изображения на оптимизированные; сохраняем в указанной папке пользователя, более подробнее я написал ниже);
- Status (отображаем: ждет оптимизации, в процесс, оптимизирован, как грфически отобразить не знаю).

Кстати, обратите внимание на окно выбора папок

2. думаю лучше сделать, чтобы диалоговые окна имели стандартное вид. Имею ввиду окна - Options и About.

3. посмотрите на изображение



как вы видите там есть функция выбора папки сохранения изображения, а так же пересохранять.
Надо сделать такую же функцию, только внизу окна проекта.
- заменяем оригинальные файлы на новые, здесь все понятно
- сохраняем в указанной папке. Лучше покажу пример.
Допустим пользоваткль указал папку оптимизации C:\Downloads\Joomla (в папке есть вложенные папки), а паку сохранения C:\Images. Цель воссоздать всю структуру вложенных папок. Делаем так, в папке C:\Images создаем папку Joomla (C:\Images\Joomla) и уже в ней создаем структуру вложенных папок. Если в папке C:\Images уже есть папка Joomla, то создаем новую папку и называем Joomla (1) и т.д.
Если пользователь просто указал файлы, то сохраняем в папке C:\Images если файлы имею одинаковые названия, то действуем как для папок.

4. Многопоточность. При оптимизации необходимо подряд запустить потоки и ждать из завершения. Только для изображений PNG.

5. Оптимизация изображений. Копируем изображение во временную папку, оптимизируем, а дальше смотрим настройки пользователя. Пока можем просто копировать во временную папку, и потом заменяем оригинальный на новый, или отправляем изображение в указанную папку.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
Re: Image Catalyst

Предупреждение За нарушение правил форума (пункт Б.5):
Имя темы должно нести смысловую нагрузку (отражать суть вопроса/проблемы)
Правильно сформулированное название темы привлекает больше внимания, и шансы получить конкретный ответ увеличиваются.


Данные правила могут пополняться локальными правилами раздела.
Как правильно называть темы

"Image Catalyst" - это неприемлемое название темы, переименуйте тему иначе она будет закрыта, а вам возможно будет выдан бан на несколько дней.

С уважением, ваш Администратор.
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
369
В общем ты сам запутался :D TreeView это нижнее окошко в моем примере, а верхнее это ListView
Выходит нам TreeView вообще не нужно, так?

Папки и файлы будут выводиться единым списком. Только папки выводить в виде списка файлов, которые в них есть (если стоит галка [включая вложенные], то список будет просто длиннее).
Вот хороший пример: MP3Gain

Список с такими колонками можно соорудить, не проблема, как и выбор папки в виде строки с галкой overwite.

Кстати, обратите внимание на окно выбора папок
Если ты про "look in subfolders" и фильтр PNG, то какое реализовать не выйдет, т.к. окно выбора папки системное, а в примере самоделка.
Но если сильно нужно, то попробуйте покопаться на офф сайте, если сможешь реализовать такое сам, то позже добавим, а пока можно сделать галку перед overwrite. Обучаемость и самостоятельность на этом форуме приветствуется :IL_AutoIt_1:

Статус обработки можно отображать цветом строки - как на скриншоте MP3Gain
Копирование во временную папку сделаю.
Стиль окон сброшу в стандартный.

Позже выложу результат.
 
Автор
L

lorents

Чайник
Сообщения
82
Репутация
1
Redline
Меня интересует именно объект TreeList, как на рисунке, в основном добавление картинок посходит именно через добавление папок, то пользователь становится удобней смотреть, что он добавил.
Сейчас можем сделать через ListView, а дальше посмотрим.

на счет стасуса согласен. :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 702
OffTopic:
Просто мысли.

Проект, безусловно, заслуживает внимания, но оптимизация PNG на практике представляется малополезной. Я не читал статью полностью, но Interlaced сейчас практически не используется, а первый пример с обезьяной, по крайней мере, некорректен, т.к. изображение ARGB было получено из Indexed, а должно быть наоборот. Оптимизация палитры? Да, но это в основном будет актуально для RGB изображений с небольшим количеством цветов, хотя это уже можно расценивать как ошибка дизайна. Наиболее часто всречающаяся ситуация - наличие Alpha-канала там, где его не должно быть. В этом случае можно перевести изображение из 32- в 24-битный формат, но это опять же невнимательность разработчика, да и выигрыш будет ~10-12%.

А более-менее вменяемое уменьшение размера JPEG без изменения качества изображения я вообще слабо представляю. Да и в большинстве случаев будет более выгодно сделать выбор в пользу GIF или того же PNG, нежели использовать JPEG. На мой взгляд, JPEG целесообразнее использовать для изображений действительно больших размеров (ЦФК), ну или там где вообще качество имеет второстепенное значение. +JPEG поддерживает CMYK.

Вообщем, как мне представляется, оптимизация данных форматов (если говорить действительно о неизменном качестве) сводится к уменьшению размера на несколько процентов, да и то, в большинстве случаев, это обусловленно невнимательностью разработчика.

А так, я использую "Automate - Batch..." из Adobe Photoshop.

:smile:




Добавлено:
Сообщение автоматически объединено:

lorents сказал(а):
...мой алгоритм оптимизации наголову превосходит.
Просто интересно, на каком ЯП написан ваш алгоритм и каким образом будет запускаться (exe, dll, COM, source и т.д.)? Просто, исходя из того, что вы собираетесь создавать временный файл в противовес работе с памятью, я думаю, что не весь код будет ваш.

Кроме того, я на 98% уверен, что многопоточность здесь будет избыточной, ну или по крайней мере без нее можно спокойно обойтись.
 
Автор
L

lorents

Чайник
Сообщения
82
Репутация
1
Yashied
Interlaced сейчас практически не используется
Согласен с вами, поддержку реализовал, но в природе таких картинок не встречал.

изображение ARGB было получено из Indexed
не совсем так, когда я нашел эту картинку, она была в ARGB, очень многие пользователи не знают, где надо использовать ARGB, а где Indexed

Оптимизация палитры? Да, но это в основном будет актуально для RGB изображений с небольшим количеством цветов
палитра только у Indexed PNG, вот статья по этому поводу

Наиболее часто всречающаяся ситуация - наличие Alpha-канала там, где его не должно быть.
не забывайте, про так называемую "чисту" под альфа каналом, я об этом писал, и провидил пример с мышкой. Здесь описана более продвинутая технология, она реальзована в проекте.

А более-менее вменяемое уменьшение размера JPEG без изменения качества изображения я вообще слабо представляю.
все дело в удалении метаданных и выбора кодировки, у меня поддержка только двух кодировок, а их намного больше, смысла реализовывать нету, в природе я их не встречал.

Да и в большинстве случаев будет более выгодно сделать выбор в пользу GIF или того же PNG, нежели использовать JPEG.
Мой вам совет, забудьте GIF, если не для анимации. Сжатие PNG выше чем у GIF.
Видел пример, где сравниваются GIF (256 цветов, выше не поддерживается) и PNG (ARGB), то тогда да GIF просто рвет. И PNG и JPEG отличные форматы, но главное знать, что и где использовать.

JPEG поддерживает CMYK.
в новой версии, будет ее поддержка.

Вообщем, как мне представляется, оптимизация данных форматов (если говорить действительно о неизменном качестве) сводится к уменьшению размера на несколько процентов, да и то, в большинстве случаев, это обусловленно невнимательностью разработчика.
и да, и нет. Да потому что это есть, и нет, так как оптимизация связана не только с этим.


Добавлено:
Сообщение автоматически объединено:

Вот она моя беда, я дал описание алгоритма, я пощупать то не дал, прошу прощения.

http://forum.ru-board.com/topic.cgi?forum=4&topic=4263

сейчас в тестовом режиме находится версия 2.2 (если, что могу выслать)


Добавлено:
Сообщение автоматически объединено:

Yashied посмотрите пожалуйста проект, многопоточность играет ключевую роль для PNG, оптимизация PNG медленная.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 702
Но почему вы не сделаете dll + SDK. Делать обвеску для кучи консольных программ не самый лучший способ, хотя...
 
Автор
L

lorents

Чайник
Сообщения
82
Репутация
1
Yashied приложения не мои, и большинство имею закрытый исходный код, а главное знаний нету таких.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 702
lorents сказал(а):
Мой вам совет, забудьте GIF, если не для анимации. Сжатие PNG выше чем у GIF.
Вы не правы. GIF еще никто не обошел для хранения всякой мелочи, например 10x10 точек. Если мне не изменяет память, то PNG по любому будет содержать полностью всю палитру (256 цветов), т.е. 1KB как минимум + самы данные.
 
Автор
L

lorents

Чайник
Сообщения
82
Репутация
1
Yashied а вы правы, сейчас протестировал.

взял смайлик :smile: и перегнал в PNG, вес увеличился на 7 байт, это конечно копейка, но ведь вы правя выходите.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
OffTopic:
Мое мнение, не запускать приложений больше чем количество ядер или процессоров. Если каждый будет грузить ядро на полную, то тормозов не избежать. Да и выигрыш по времени максимальный именно при таком раскладе. Дальнейшее увеличение количества потоков просто вызовет конкуренцию среди них за процессорное время.
А вообще, я бы выбрал ЯП с этой самой поддержкой многопоточности/мультипроцессорности.
 
Автор
L

lorents

Чайник
Сообщения
82
Репутация
1
Kaster
Я с вами полностю согласен, я еще думал как автоматчики сделать оптимальный выбор кол-ва потоков с учетом нагрузки на CPU.
а что такое ЯП?
 
Верх