IconEditor
Скачать: yandex
Редактор иконок, но пока иконка сохраняется в bmp и всего лишь два инструмента, карандаш и заливка.
PureBasic - форум |
Привет, Гость! Войдите или зарегистрируйтесь.
Вы здесь » PureBasic - форум » PureBasic для Windows » IconEditor
IconEditor
Скачать: yandex
Редактор иконок, но пока иконка сохраняется в bmp и всего лишь два инструмента, карандаш и заливка.
А почему екзешник такой гигантский? 350 килобайт — не слишком ли много только для того, чтобы раскрасить пиксели по щелчку мыши в определённый цвет?
Замабувараев
Это он еще маленький. Если добавить jpg, tga, tiff вообще запредельный будет. Если для чтения нужен декодер, то для записи нужен енкодер. Убери оба png и скомпилируй, увидишь как он быстро в 100 кб превратится. Gif -15 кб, поэтому я часто иконки в этом формате делаю, чтобы не добавлять к проге размером 70кб декодер png размером 150 кб, декодер больше моей проги получается.
Отредактировано AZJIO (22.11.2023 13:12:16)
Замабувараев, наверно фильтр подключен
Azjio, есть Dll для вращения, надо?
в качестве недостатка, работает только с РВ
Azjio, а потянешь?
есть не менее 10 готовых иконочников, именно иконочников, а не редакторов
вращения
У меня пиксели в массиве, а массив я поворачивать умею, в любом случае давай, посмотрю передовые технологии. Кстати могу тон, насыщенность, яркость встроить, только какова будет скорость, как бв не завязнуть в оптимизаторах, если будет работать медленно
Иконки — это файлы с расширением *.ico. Какие ещё жипеги и пнг?
посмотрю передовые технологии
Умножить вектор на матрицу не такая уж и передовая технология.
Замабувараев
то есть в png и gif ты никогда иконки не сохранял? И не открывал png чтобы сделать иконку? На сайте значков тебе прям так и дали в ico-формате, в Linux вообще не понимает ico, там иконки в png и векторые, а ico это приблуда винды.
Умножить вектор на матрицу не такая уж и передовая технология.
Вращать ротор векторного поля?
Обновил, теперь есть вращение на 90 градусов вправо/влево и есть регулировка тон/яркость/насыщенность
Отредактировано AZJIO (23.11.2023 00:25:22)
вращение картинок, 7 фиксированных и на угол 1-359 градусов, пробуй
https://disk.yandex.ru/d/KBMUj9dkoN0Bzw
AZJIO, сразу делай сохранение всего что изменил чел, чтобы прога стартовала в том же положении
Замабувараев, иконочник должен уметь работать с другими форматами, иначе он ни кому не нужен
тоже ico не использую где можно это Г. не использовать
newJS
случайно не GdipRotateMatrix использует? Просто в AutoIt3 GDI я использовал и переводил, сразу вспомнил про любой угол (_GDIPlus_MatrixRotate).
Отредактировано AZJIO (23.11.2023 03:28:01)
то есть в png и gif ты никогда иконки не сохранял? И не открывал png чтобы сделать иконку?
А что такое иконки? Если это просто картинка маленького размера, то с такими картинками любой рыдактор умеет работать, даже Пеинт умеет работать с файлами 1x1 пиксель.
А вот если бы программа умел иконки создавать, как заявлено в названии, было бы хорошо.
Вращать ротор векторного поля?
Вы всё усложняете.
В автоматическом режиме устанавливаем матрицу трансляции (поворот, отражение, сдвиг, перенос, масштабирование) в графический контекст и выводим картинку. Это умеет делать даже GDI на Win95.
В ручном режиме перед выводом точки умножаем вектор на матрицу и рисуем точку.
AZJIO, не, апишная функция PlgBlt_()
ты реально делать собрался или поиграешься и бросишь?
то что я увидел и на детский сад не тянет
ты реально делать собрался или поиграешься и бросишь?
именно так, если только не увижу какой нибудь функции которой мне не достаёт, а я могу сделать. Обычные бесплатные "IcoFX 1.6", "Greenfish Icon Editor Pro 4.2", "Gimp" с этим справляются выше крыши, в "Gimp" так вообще доступны все возможности полноценного комбайн-редактора. Так что мы можем только поиграться и пристроить это для рисования уровней игры или взять какой нибудь алгоритм для своих целей.
newJS
Мне не нравится иконочные масштабирование и вращение, кроме случая, когда иконка изначально берётся с рисунка размером 500х500 и больше, так как такие манипуляции происходят потерей качества и размытием, а иконки должны быть контрастными. Практически иконку 16х16 чуть ли не попиксельно приходится рисовать, да, сначала масштабируешь форму, о потом видя линии рисуешь свою иконку. Даже просто сдвиг на "пол пикселя" приводит иконку ничтожный результат, поэтому приходилось перед масштабированием крупной иконки несколько раз сдвигать на пиксел, чтобы контрастные линии не попадали на границу пикселя и не расплывались бы на две полу-тусклые линии.
А вот если бы программа умел иконки создавать, как заявлено в названии, было бы хорошо.
Нет времени, есть другие идеи, вам это тоже не нужно, для этого есть редакторы, а если нужно, то вы сами можете дерзать.
Отредактировано AZJIO (23.11.2023 17:23:22)
Обновление
Добавлен русский язык
Добавлено сохранение настроек
Иконки встроены в исполняемый файл.
Поддержка Dpi (проверка на 125% и 150%)
Кнопка цвета вызывает стандартный диалог выбора цвета.
Перераспределение элементов окна
Добавлено поле ввода и предпросмотра цвета в виде шестнадцатеричных данных
Нашёл такую функцию SaveIcon и сделал для неё перевод, правда делать я его начал уже после некоторых модификаций, так что снизу не оригинал, я пытался вырезать поддержку курсора, чтобы упростить код и переделать его на работу с изображением, вместо иконки, но пока не получилось, и не знаю получится ли.
; srod ; https://www.purebasic.fr/english/viewtopic.php?t=23387 !!!уже модернизировал, это не оригинал !!! ; SaveIcon. ; By Stephen Rodriguez 2006 (Обновлено 2010). ; Purebasic 4.5 ; Этот небольшой include-файл позволяет сохранить один значок/курсор в файле .ico/.cur. ; Расширение, чтобы включить несколько значков/курсоров в один файл было бы простым. ; СИНТАКСИС: SaveIcon(hIcon, filename$) ; где hIcon — это дескриптор значка/курсора, загруженного из файла ресурсов или с помощью LoadImage_() и т. д. ; ПРИМЕЧАНИЕ. ; i) Эту библиотеку можно использовать только со значками/курсорами, которые уже хранятся в памяти. ; (либо загруженный с диска, либо созданный с помощью CreateIconIndirect_() и т. д.) и ; сохраняет значок/курсор в файл в том же формате (глубина и т. д.), что и хранящийся внутри Windows. ; Однако этот код можно "легко" адаптировать для создания значков/курсоров с нуля, ; используя Purebasic (где изображения хранятся в любом формате), а затем, ; используя адаптированный из этой библиотеки код, сохранять в формат .ico/.cur. ; Это просто вопрос возни с таблицами цветов и т. д. ; ii) Если вы используете эту библиотеку для сохранения значка/курсора, загруженного с помощью LoadImage_(), ; может показаться, что новый значок/курсор имеет другой размер. Это произойдет потому, что исходный ; файл .ico/.cur содержит несколько значков разных размеров. ; Проводник Windows может сообщать об одном размере, пока вы загружаете другой и т. д. ; TODO (возможно!) ; -Расширьте код, чтобы сохранить несколько значков/курсоров в одном файле .ico. ; -Расширить до файлов .cur курсора (ГОТОВО!) ; ************************************************************************************************** ; Результат = ненулевой, если нет ошибок. Procedure.i SaveIcon(hIcon, filename$) Protected result, iconinfo.ICONINFO, hbmMask, hbmColor Protected cbitmap.BITMAP, cwidth, cheight, cbitsperpixel, colorcount, colorplanes Protected mbitmap.BITMAP, mwidth, mheight Protected file, imagebytecount, hdc, oldbitmap, mem, bytesinrow, temp Protected *bitmapinfo.BITMAPINFO ; Получите информацию об иконке. If Not GetIconInfo_(hIcon, iconinfo) Debug 1 ProcedureReturn 0 EndIf ; Недопустимый дескриптор значка. ; Выделите память для структуры BITMAPINFO + таблицы цветов на 256 записей. *bitmapinfo = AllocateMemory(SizeOf(BITMAPINFO) + SizeOf(RGBQUAD) << 8) If *bitmapinfo = 0 ProcedureReturn 0 EndIf ; Получите растровое изображение маски (И), которое, если значок черно-белый монохромный, содержит цветное растровое изображение. hbmMask = iconinfo\hbmMask GetObject_(hbmMask, SizeOf(BITMAP), mbitmap) mwidth = mbitmap\bmWidth mheight = mbitmap\bmHeight ; Получите цвет (XOR) bitmap. hbmColor = iconinfo\hbmColor If hbmColor GetObject_(hbmColor, SizeOf(BITMAP), cbitmap) cwidth = cbitmap\bmWidth cheight = cbitmap\bmHeight cbitsperpixel = cbitmap\bmBitsPixel If cbitsperpixel = 0 cbitsperpixel = 1 EndIf If cbitsperpixel < 8 colorcount = Pow(2, cbitsperpixel) ; colorcount = 0, если 8 или более бит на пиксель (bpp). EndIf colorplanes = cbitmap\bmplanes Else ; Монохромный значок (2 цвета, чёрный и белый или другие, то есть 0 и 1). cwidth = mwidth cheight = mheight / 2 cbitsperpixel = 1 colorcount = 2 colorplanes = 1 mheight = cheight EndIf ; Все готово для создания файла. file = CreateFile(#PB_Any, filename$) If file ; Записывает данные. ; word = 0 WriteWord(file, 0) ; (резервный) ; word = 1 для значка, 2 для курсора. WriteWord(file, 1) ; (тип) 1 - значок, 2 - курсор. ; word = количество иконок в файле. WriteWord(file, 1) ; (число иконок) ***ИЗМЕНИТЕ ЕСЛИ КОД ПОДДЕРЖИВАЕТ БОЛЬШЕЕ ЧИСЛО ЗНАЧКОВ*** ; 16-байтовая структура ICONDIRENTRY, по одному на каждый значок. WriteByte(file, cwidth) ; ширина WriteByte(file, cheight) ; высота WriteByte(file, colorcount) ; цветов в палитре WriteByte(file, 0) ; резервный . ; If ficon = 1 ; иконка. WriteWord(file, colorplanes) ; (число плоскостей: 0 или 1) Должно быть равно 1, - но на всякий случай! WriteWord(file, cbitsperpixel) ; bpp - бит на пиксель ; EndIf WriteLong(file, 0) ; (размер растра, см FileSeek на 14 далее) ВРЕМЕННО! НАМ НУЖНО ВЕРНУТЬ, КОГДА МЫ ЗНАЕМ ТОЧНОЕ КОЛИЧЕСТВО. ; Размер (InfoHeader + ANDbitmap + XORbitmap) WriteLong(file, Loc(file) + 4) ; (позиция BITMAPINFOHEADER) FilePos, где начинается InfoHeader ; Теперь данные изображения в виде BITMAPINFOHEADER (40 байт) + карта цветов для цветового растрового изображения. ; + биты цветного растрового изображения + биты растрового изображения маски. Глоток! По одному на каждую иконку. ; 40-байтовая структура BITMAPINFOHEADER. imagebytecount = SizeOf(BITMAPINFOHEADER) WriteLong(file, imagebytecount) ; Should be 40. WriteLong(file, cwidth) WriteLong(file, cheight + mheight) ; Комбинированные высоты цвета + изображения маски. WriteWord(file, colorplanes) ; Должно быть равно 1, - но на всякий случай! WriteWord(file, cbitsperpixel) WriteLong(file, 0) ; Сжатие. WriteLong(file, 0) ; Размер изображения. Допустимо установить нулевое значение, если сжатие отсутствует. WriteLong(file, 0) ; Неиспользуется. WriteLong(file, 0) ; Неиспользуется. WriteLong(file, 0) ; Неиспользуется. WriteLong(file, 0) ; Неиспользуется. ; Цветовая карта. Применяется только для <= 8 бит на пиксель. hdc = CreateCompatibleDC_(0) ; Нужен для того, чтобы получить таблицу цветов. If hbmColor = 0 ; Монохромный значок. WriteLong(file, #Black) WriteLong(file, #White) imagebytecount + SizeOf(rgbquad) * 2 ElseIf cbitsperpixel <= 8 ; Включает 1-битные немонохромные значки. ; Получите таблицу цветов. temp = Pow(2, cbitsperpixel) bytesinrow = SizeOf(rgbquad) * temp mem = AllocateMemory(bytesinrow) oldbitmap = SelectObject_(hdc, hbmColor) GetDIBColorTable_(hdc, 0, temp, mem) WriteData(file, mem, bytesinrow) ; Напишите таблицу цветов. FreeMemory(mem) SelectObject_(hdc, oldbitmap) imagebytecount + bytesinrow EndIf ; Теперь биты цветного изображения. Для этого мы используем GetDiBits_(). bytesinrow = (cwidth * cbitsperpixel + 31) / 32 * 4 ; Выровнено по границе 4 байта. bytesinrow * cheight mem = AllocateMemory(bytesinrow) *bitmapinfo\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER) *bitmapinfo\bmiHeader\biWidth = cwidth *bitmapinfo\bmiHeader\biPlanes = colorplanes *bitmapinfo\bmiHeader\biBitCount = cbitsperpixel If hbmColor *bitmapinfo\bmiHeader\biHeight = cheight GetDIBits_(hdc, hbmColor, 0, cheight, mem, *bitmapinfo, #DIB_RGB_COLORS) Else ; Монохромное цветное изображение — это нижняя половина изображения маски. *bitmapinfo\bmiHeader\biHeight = 2*cheight GetDIBits_(hdc, hbmMask, 0, cheight, mem, *bitmapinfo, #DIB_RGB_COLORS) EndIf WriteData(file, mem, bytesinrow) FreeMemory(mem) imagebytecount + bytesinrow ; Теперь биты изображения маски. Для этого мы используем GetDiBits_(). bytesinrow = (mwidth + 31) / 32 * 4 ; Выровнено по границе 4 байта. bytesinrow * mheight mem = AllocateMemory(bytesinrow) *bitmapinfo\bmiHeader\biWidth = mwidth *bitmapinfo\bmiHeader\biPlanes = 1 *bitmapinfo\bmiHeader\biBitCount = 1 If hbmColor *bitmapinfo\bmiHeader\biHeight = mheight GetDIBits_(hdc, hbmMask, 0, mheight, mem, *bitmapinfo, #DIB_RGB_COLORS) Else *bitmapinfo\bmiHeader\biHeight = 2*mheight GetDIBits_(hdc, hbmMask, mheight, mheight, mem, *bitmapinfo, #DIB_RGB_COLORS) EndIf WriteData(file, mem, bytesinrow) FreeMemory(mem) imagebytecount + bytesinrow DeleteDC_(hdc) ; Наконец, возвращение на поле, которое мы пропустили. FileSeek(file, 14) WriteLong(file, imagebytecount) CloseFile(file) result = 1 ; Сигнал, что все в порядке. Else result = 0 EndIf DeleteObject_(hbmMask) ; Это копии, созданные в результате GetIconInfo_(), и поэтому их необходимо удалить. DeleteObject_(hbmColor) FreeMemory(*bitmapinfo) ProcedureReturn result EndProcedure
у меня такой код есть, скорей всего оригинал
может что поимеешь
; German forum: ; Author: PureFan ; Date: 23. March 2003 ; OS: Windows ; Demo: Yes ;"--------------------------------------------------------------------- ; Bilder als *.ICO und *.CUR - Datei abspeichern ;"--------------------------------------------------------------------- ;Verwenden sie diese Variable, wenn sie keine transparenz verwenden wollen! ;Global NoTransparent PokeB(@NoTransparent.l+3,1) ;Schreibt ein Byte (0-255) in die aktuell geцffnete Datei Procedure.l WriteByte2(val.l) WriteData(@val,1) EndProcedure ;Speichert das Bild, auf dem gerade gezeichnet wird, in einer *.ICO ;(HotspotX und HotspotY muss 0 sein!) oder in einer *.CUR-Datei! Procedure.l SaveIcon(FileName.s,TransparentColor.l,HotspotX.l,HotspotY.l) ;Der Hotspot muss sich innerhalb des Bildes befinden! If HotspotX>32:HotspotX=32:ElseIf HotspotX<0:HotspotX=0:EndIf If HotspotY>32:HotspotY=32:ElseIf HotspotY<0:HotspotY=0:EndIf ;Цffnet die Datei If CreateFile(0,FileName)=0 ProcedureReturn 0 EndIf ;Schreibt zuerst den HEADER fьr eine 32x32 Pixel groЯe ICO-Datei Restore ICON_HEADER_256_COLORS For I=1 To 62 Read ThisValue If I=$B WriteByte2(HotspotX) ElseIf I=$D WriteByte2(HotspotY) Else WriteByte2(ThisValue) EndIf Next I ;Erstellt eine Palette mit 256 Farben Dim UsedColors.l(255) UsedColors(0)=RGB(0,0,0) UsedColorCnt.l=1 For Y=31 To 0 Step -1 For X=0 To 31 Step 1 Farbe.l=Point(X,Y) AddToList.l=1 For I=0 To UsedColorCnt If Farbe=UsedColors(I) AddToList=0 I=UsedColorCnt EndIf Next I If UsedColorCnt=255 And AddToList MIN_I=1 MIN_DIF=0 For I=1 To UsedColorCnt If Abs(Farbe-UsedColors(I))<MIN_DIF Or I=1 MIN_I=I MIN_DIF=Abs(Farbe-UsedColors(I)) EndIf Next I NEW_RED=(Red(Farbe)+Red(UsedColors(MIN_I)))/2 NEW_GREEN=(Green(Farbe)+Green(UsedColors(MIN_I)))/2 NEW_BLUE=(Blue(Farbe)+Blue(UsedColors(MIN_I)))/2 UsedColors(MIN_I)=RGB(NEW_RED,NEW_GREEN,NEW_BLUE) ElseIf UsedColorCnt<>255 And AddToList UsedColors(UsedColorCnt)=Farbe UsedColorCnt+1 EndIf Next X Next Y ;Schreibt die Palette in die Datei For I=0 To UsedColorCnt WriteByte(Blue(UsedColors(I))) WriteByte(Green(UsedColors(I))) WriteByte(Red(UsedColors(I))) WriteByte(0) Next I ;Fьr alle freien Eintrдge wird die Farbe SCHWARZ eingefьgt For I=UsedColorCnt+1 To 255 WriteLong(0) Next I ;Schreibt das Bild in die Datei For Y=31 To 0 Step -1 For X=0 To 31 Step 1 Farbe.l=Point(X,Y) If Farbe<>TransparentColor MIN_I=0 For I=0 To UsedColorCnt If Abs(Farbe-UsedColors(I))<MIN_DIF Or I=0 MIN_I=I MIN_DIF=Abs(Farbe-UsedColors(I)) EndIf Next I Farbe=MIN_I Else Farbe=0 EndIf WriteByte2(Farbe) Next X Next Y ;Schreibt am Ende eine Liste, damit der Computer weiЯ, welche Pixel transparent sind For Y=31 To 0 Step -1 For X=0 To 31 Step 8 LastByte.l=0 For I=0 To 7 Farbe.l=Point(X+I,Y) If Farbe=TransparentColor Select I Case 7:OrVal=1 Case 6:OrVal=2 Case 5:OrVal=4 Case 4:OrVal=8 Case 3:OrVal=16 Case 2:OrVal=32 Case 1:OrVal=64 Case 0:OrVal=128 EndSelect LastByte|OrVal EndIf Next I WriteByte2(LastByte) Next X Next Y ;Fertig! SchlieЯt die Datei CloseFile(0) ProcedureReturn 1 ;Der HEADER fьr eine ICO-Datei DataSection ICON_HEADER_256_COLORS: Data.l $00,$00,$01,$00,$01,$00,$20,$20,$00,$00,$00,$00,$00,$00,$A8,$08 Data.l $00,$00,$16,$00,$00,$00,$28,$00,$00,$00,$20,$00,$00,$00,$40,$00 Data.l $00,$00,$01,$00,$08,$00,$00,$00,$00,$00,$80,$04,$00,$00,$00,$00 Data.l $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 EndDataSection EndProcedure ;"--------------------------------------------------------------------- ; BEISPIEL ;"--------------------------------------------------------------------- MessageRequester("Bmp2Ico","Bitte wдhlen sie im folgenden Dialog das Bitmap aus, das in eine Ico umgewandelt werden soll!",0) BmpDatei.s=OpenFileRequester("BMP-Datei цffnen","","Bitmaps|*.bmp",0) If BmpDatei="" End EndIf IcoDatei.s=SaveFileRequester("Speichern als ICO-Datei","","Icons|*.ico",0) If IcoDatei="" End EndIf If LoadImage(0,BmpDatei)=0 MessageRequester("Fehler!","Ungьltiges Dateiformat!",0) EndIf StartDrawing(ImageOutput()) SaveIcon(IcoDatei,NoTransparent,0,0) ;Ico-Dateien haben keinen Hotspot StopDrawing() MessageRequester("Info!","Datei erfolgreich abgespeichert!",0) ; ExecutableFormat=Windows ; FirstLine=1 ; EOF
newJS
мне дали идеальные функции сохранения в иконку, но я пока не добавлял.
Интересный алгоритм заполнения при заливке ведром/банкой. Проверяется близ лежащие пикселы в рекурсии, но я подумал, зачем проверять 4 направления, если с одного из направлений делается как бы вход, то есть если слева от пиксела нужный для заливки квадрат, то вызывается повтор для обследования пискелов вокруг этого пиксела, но если мы пришли слева, то левый пиксел можно не проверять. В итоге вместо 4 направлений проверяется 3 и снижение задач на 25% ну и быстрей соответственно на 25%. Этот же алгоритм используется в CubePicker, потом он перешёл в IconEditor сейчас в BallBrick для взрывающихся. Поэтому я и хотел сделать оптимизацию, так как в CubePicker это используется при наведении мыши, то есть очень быстро, в IconEditor залить иконку 48х48=2304 это пробежаться по 2 тыс. пикселам, а в BallBrick за 1/60 сек взорвать кирпичи - вычислить близлежащие. Но в CubePicker я ещё не встроил эту оптимизацию. В связи с этим интересно как это делается в FillArea(). Как вариант попробовать сделать копию изображения в image и залить с помощью FillArea(), а потом попиксельно вернуть обратно в массив.
Вы здесь » PureBasic - форум » PureBasic для Windows » IconEditor