Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Как записать растр в файл? Как прочесть растр из файла?
|
|||
|---|---|---|---|
|
#18+
Создаю "виртуальное" окно и растр в нем API-функциями hBM = CreateCompatibleBitmap(hGetDC, W, H) hDC = CreateCompatibleDC(0) Q = SelectObject(hDC, hBM) Потом рисую в этом окне. Как сохранить рисунок в файл? И, наоборот, как прочесть в такое окно растр из файла? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.05.2010, 08:13 |
|
||
|
Как записать растр в файл? Как прочесть растр из файла?
|
|||
|---|---|---|---|
|
#18+
litvin44, Можно (в смысле, один из способов) воспользоваться стандартными функциями SavePicture() и LoadPicture(). Для этого надо завернуть GDI-ный битмап в COM-объект, поддерживающий интерфейс IPictureDisp, см. здесь функцию CreateIPictureDispFromHBITMAP(). Соответственно, запись: Код: plaintext Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.05.2010, 11:23 |
|
||
|
Как записать растр в файл? Как прочесть растр из файла?
|
|||
|---|---|---|---|
|
#18+
Бенедикт, Спасибо за подсказку. К сожалению, CreateIPictureDispFromHBITMAP() не работает так как: - не подключена библиотека Lib "olepro32" – где ее взять? - что за тип PICTYPE (входит в структуру PicBmp)? Зато фраза "Pic.Handle имеет значение дескриптора битмапа" оказалась ключевой. С чтением проблема снята: Dim hDC As Long, Pic As IPictureDisp Set Pic = LoadPicture(путь) SelectObject hDC, Pic.Handle Потом можно что-то нарисовать на hDC, и сохранить с помощью SavePicture Pic, путь Но, для того, что бы сохранить, сначала приходится прочесть файл с картиной нужных ширины и высоты. А создать Pic "с нуля" не получается ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.05.2010, 23:04 |
|
||
|
Как записать растр в файл? Как прочесть растр из файла?
|
|||
|---|---|---|---|
|
#18+
litvin44К сожалению, CreateIPictureDispFromHBITMAP() не работает так как: - не подключена библиотека Lib "olepro32" – где ее взять? - что за тип PICTYPE (входит в структуру PicBmp)?1) Что значит "не работает"? Подробности. 2) Что значит "не подключена"? olepro32.dll входит в состав ОС. Это не ActiveX-библиотека, её не надо регистрировать или подключать в диалоге References. Если её нет в системной папке (WINDOWS\System32), с системой что-то не в порядке. 3) Перечислимый тип PICTYPE описан в том же коде.litvin44С чтением проблема снята: Dim hDC As Long, Pic As IPictureDisp Set Pic = LoadPicture(путь) SelectObject hDC, Pic.Handle Потом можно что-то нарисовать на hDC, и сохранить с помощью SavePicture Pic, путьНу, можно, конечно, и сразу SelectObject() делать... Это короткий путь, Вы сами наткнулись, на то к чему он приводит. (Кстати, Вы что, опять (вспоминая прошлую тему) игнорируете утечку ресурсов, не запоминая старый HBITMAP?) Но лучше этого не делать и рисовать IPictureDisp на hDC, вызывая метод IPictureDisp.Render(), он, например, прозрачность понимает (для поддерживаемых форматов).litvin44Но, для того, что бы сохранить, сначала приходится прочесть файл с картиной нужных ширины и высоты. А создать Pic "с нуля" не получаетсяСоздаёте (как сами и показали в первом сообщении!) новый битмап через CreateCompatibleBitmap(), выбираете в контексте устройства, запоминая попутно старый, рисуете сцену, восстанавливаете старый битмап, далее скармливаете (новый) битмап функции CreateIPictureDispFromHBITMAP(), далее вызываете SavePicture(). Посмотрите, кстати, описание OleCreatePictureIndirect(), разберитесь с её третьим параметром (он же третий параметр CreateIPictureDispFromHBITMAP()). Он определяет, когда и кем будет уничтожен битмап. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2010, 01:43 |
|
||
|
Как записать растр в файл? Как прочесть растр из файла?
|
|||
|---|---|---|---|
|
#18+
litvin44, взяв пример из темы по ссылке: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2010, 02:25 |
|
||
|
Как записать растр в файл? Как прочесть растр из файла?
|
|||
|---|---|---|---|
|
#18+
Бенедикт, 1) Не работает в смысле VB-5 (который используется на работе, чтоб избежать проблем с ОБЭП) дает сообщение: Private Enum types cannot be used as parameter or return types for public procedures, or as public data members В VB-6 работает 2) "разберитесь с её третьим параметром" – не понял. Это как-то связано с тем, что hbmMem НЕ удаляется в вашем примере? 3) Пожалуйста, объясните мне про удаление, и, заодно, проверьте код. Вариант 1 (по вашим рекомендациям): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Вариант 2 (свой): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Код: plaintext 1. А в вар.2 выдает ошибку, что логично, т.к. hBM уже удалено ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2010, 15:59 |
|
||
|
Как записать растр в файл? Как прочесть растр из файла?
|
|||
|---|---|---|---|
|
#18+
litvin441) Не работает в смысле VB-5 (который используется на работе, чтоб избежать проблем с ОБЭП) дает сообщение: Private Enum types cannot be used as parameter or return types for public procedures, or as public data members В VB-6 работаетСтранно, там и типы private, и функция объявлена с private. Можно вместо As PICTYPE написать As Long и забыть.litvin442) "разберитесь с её третьим параметром" – не понял. Это как-то связано с тем, что hbmMem НЕ удаляется в вашем примере?Да.litvin443) Пожалуйста, объясните мне про удаление,Если флаг fPictureOwnsHandle равен 0, дескриптор битмапа удаляете сами, и сами следите, чтобы не было к возвращённому COM-объекту обращения, ожидающего, что в объекте что-то есть. Если флаг не равен 0, COM-объект сам решает, когда удалить битмап (точнее, GDI-объект, т. к. это может быть не только битмап). Если количество ссылок на объект становится равным 0, битмап удаляется. Т.е. время жизни битмапа не превышает время жизни COM-объекта, и, например, если переменная, содержащая ссылку на него, вышла за область видимости, счётчик ссылок внутри объекта уменьшается на 1, если он при этом стал равным 0 - см. выше. Т.о., о DeleteObject(), особенно если битмап используется в нескольких местах, голова не болит.litvin44и, заодно, проверьте код. Вариант 1 (по вашим рекомендациям): ...С виду правильно. Я бы (чистая вкусовщина) код "удаление" поменял местами с "в файл".litvin44Вариант 2 (свой): ... Код: plaintext 1. 2. Код: plaintext 1. litvin44А в вар.2 выдает ошибку, что логично, т.к. hBM уже удаленоЛогично. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2010, 18:18 |
|
||
|
Как записать растр в файл? Как прочесть растр из файла?
|
|||
|---|---|---|---|
|
#18+
Бенедикт, «Можно вместо As PICTYPE написать As Long и забыть.» - не работает. После этого начинает ругаться на OleCreatePictureIndirect (Именно по этому я ошибочно написал во 2-м посте, что «не подключена библиотека Lib "olepro32" – где ее взять?» - не разобравшись, подумал, что декларация не правильная, а API-View такой функции не показывает) Мне трудно с вами спорить, как с НАМНОГО более квалифицированным, но имхо, как раз во 2-м варианте соблюдено «открытие/закрытие скобок» SelectObject сам по себе уничтожает прошлый объект (или нет?) В 1-м варианте это уничнотжение hBM срокой SelectObject hDC, hbmOld (при этом, непонятно, куда девается hbmOld) Во 2-м это явное уничтожение DeleteObject hBM строкой DeleteObject hBM (без ожидания, когда это сделает CreateIPictureDispFromHBITMAP). Кстати, напишите, пожалуйста, что означают параметры CreateIPictureDispFromHBITMAP и как их применять – сам я не разберусь. Личный вопрос: а как вы запомнили мою прошлую тему? И (набрался наглости) как у вас проконсультироваться в будущем? Дело в том, что я НЕ программист, но надо работать в VBA (сейчас в CorelDraw) а он сильно урезанный по сравнению с VB, вот и приходится идти окольными тропами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.05.2010, 22:40 |
|
||
|
Как записать растр в файл? Как прочесть растр из файла?
|
|||
|---|---|---|---|
|
#18+
litvin44«Можно вместо As PICTYPE написать As Long и забыть.» - не работает. После этого начинает ругаться на OleCreatePictureIndirect (Именно по этому я ошибочно написал во 2-м посте, что «не подключена библиотека Lib "olepro32" – где ее взять?» - не разобравшись, подумал, что декларация не правильная, а API-View такой функции не показывает)У меня нет VB 5, чтобы посмотреть. Проверьте, что в проект подключена библиотека типов OLE Automation, что код помещён в общем модуле (не модуле класса/формы), что все UDT и Declare описаны как Private.litvin44имхо, как раз во 2-м варианте соблюдено «открытие/закрытие скобок» SelectObject сам по себе уничтожает прошлый объект (или нет?)Нет. Это было бы странно - я нарисовал что-то в контексте устройства на битмапе, хочу сменить битмап, и нарисовать что-то другое, а SelectObject() взяла бы и убила первый битмап. Для этого есть DeleteObject(). Обратите внимание на описание SelectObject() :MSDN Library, SelectObject FunctionThis function returns the previously selected object of the specified type. An application should always replace a new object with the original, default object after it has finished drawing with the new object. litvin44В 1-м варианте это уничнотжение hBM срокой SelectObject hDC, hbmOld (при этом, непонятно, куда девается hbmOld)Не уничтожение, а выбор исходного объекта данного типа (битмап). hbmOld будет "убит" в DeleteDC(), совместно с другими ресурсами (кистями, шрифтами, регионами и т. д.). Я в отладочном коде, бывает, пишу SelectObject hDC, hbmOld: hbmOld = 0, чтобы 1) показать, что судьба этого объекта меня не интересует, за него теперь отвечает система; 2) случайно не воспользоваться значением этого дескриптора; 3) при отладке в окне локальных переменных видеть потенциально не освобождённые ресурсы (дескрипторы, не равные 0). hBM же уничтожается при уменьшении ссылок на COM-объект, в который завёрнут hBM, до 0, в данном случае при достижении End Sub. Можно явно уменьшить количество ссылок: Set IPD = Nothing.litvin44Во 2-м это явное уничтожение DeleteObject hBM строкой DeleteObject hBM (без ожидания, когда это сделает CreateIPictureDispFromHBITMAP).Хотите явно уничтожать битмап вызовом DeleteObject(), вызывайте CreateIPictureDispFromHBITMAP с параметрами (hBM, 0, 0). CreateIPictureDispFromHBITMAP() не уничтожает битмап, а заворачивает его в COM-объект и возвращает на него ссылку.litvin44Кстати, напишите, пожалуйста, что означают параметры CreateIPictureDispFromHBITMAP и как их применять – сам я не разберусь.Первый параметр - дескриптор битмапа, второй параметр - дескриптор палитры (может понадобиться если битмап создаётся совместимым с устройством с глубиной цвета 8 и менее бит, ныне это редкий случай, обычно, и по умолчанию, этот параметр равен 0), третий параметр - если 0, DeleteObject() делаете сами, если не 0 (по умолчанию), DeleteObject() делает возвращаемый функцией COM-объект.litvin44Личный вопрос: а как вы запомнили мою прошлую тему?Показалась знакомой комбинация тематики и участника форума, посмотрел в профиль участника.litvin44И (набрался наглости) как у вас проконсультироваться в будущем?Пишите в форум, если считаете, что тема имеет шанс кому-то ещё пригодиться в дальнейшем, пишите на адрес в моём профиле, если такого шанса нет, иле не хотите выносить тему на общее обозрение. Но почту я читаю реже форума.litvin44Дело в том, что я НЕ программист, но надо работать в VBA (сейчас в CorelDraw) а он сильно урезанный по сравнению с VB, вот и приходится идти окольными тропами.Насколько я понимаю, CorelDraw обычный VBA-хост, по языку не урезан, а стандартно подключаемые в проект библиотеки свои. По библиотекам не скажу, а то, что решается языком и внешними библиотеками, в любых VBA-хостах должно работать одинаково. А системные API - это вполне прямые тропы, по ним хоть документацию можно найти и примеры. Но кода, да, больше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2010, 13:45 |
|
||
|
|

start [/forum/topic.php?fid=60&fpage=127&tid=2159749]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
27ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
76ms |
get tp. blocked users: |
2ms |
| others: | 9ms |
| total: | 151ms |

| 0 / 0 |
