PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Нужно получить доступ к памяти после LoadImage()


Нужно получить доступ к памяти после LoadImage()

Сообщений 1 страница 8 из 8

1

нужна инфа из заголовка
ReadFile() даёт искомое, но это двойная загрузка файла
есть способ проще? может что в API есть?

0

2

CatchImage ?
https://www.purebasic.fr/english/viewto … 13#p580713

0

3

CatchImage(#Image, *MemoryAddress [, Size])
*MemoryAddress Адрес области памяти, из которой требуется загрузить изображение.
этот адрес мне и нужен, как его получить?

0

4

Попробовал EncodeImage(), но он как я понимаю делает копию изображения и даёт на него указатель. В этом способе нет необходимости переделывать LoadImage(), просто указать номер изображения в EncodeImage(0). Функция перекодирует изображение, тут я не знаю вернёт ли точную бинарную копию или привнесёт изменения (добавит/убавит число цветов). Скорее перекодирует разжатые данные, если bmp является сжатый с помощью индексированных цветов.

Код:
*ptr=EncodeImage(0)
If CreateFile(0, "C:\folder\1.bmp")
	WriteData(0, *ptr,MemorySize(*ptr))
	CloseFile(0)
EndIf

ReadFile() даёт искомое, но это двойная загрузка файла

Если открыть файл, а потом выполнить CatchImage, то как я понимаю это не двойная загрузка файла.
Хотя сделал пример доказывающий, что CatchImage делает свою копию, но в любом случае к диску обращается однократно.
Ещё момент, все сжатые форматы являются сжатыми только на диске, но когда они отображаются на экране, они должны иметь разжатый вид, так как пиксель экрана не является индексированным и каждая точка на экране получает весь цвет, отсюда вывод, это разжатие происходит в памяти или только при выводе видеокартой, тогда в видюхе был бы аппаратный декодер форматов. Есть подозрение что разжатие происходит именно в памяти и возможно результат LoadImage или CatchImage содержит указатель на разжатые данные и тогда указатель на них не одно и тоже что бинарные данные файла.

Код:
EnableExplicit

#Image = 0
#File = 0

Define isImg, *mem, length,q, path$, bytes

isImg = 0

path$ = #PB_Compiler_Home+"Examples\Sources\Data\GeeBee2.bmp"
If path$
	If ReadFile(#File, path$)
    length = Lof(#File)
    *mem = AllocateMemory(length)
    If *mem
    	bytes = ReadData(#File, *mem, length)
    	If bytes
;         Debug bytes
;         ShowMemoryViewer(*mem , 48)
        isImg = CatchImage(#Image , *mem, bytes)
        FreeMemory(*mem)
    	EndIf
    EndIf
    CloseFile(0)
	EndIf
EndIf

; Debug isImg
If isImg
	If OpenWindow(0, 0, 0, 426, 128, "EncodeImage", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	    ImageGadget(0, 0, 0, 128, 128, isImg)
	    Repeat
	    Until WaitWindowEvent() = #PB_Event_CloseWindow
	EndIf
EndIf

Отредактировано AZJIO (20.02.2022 08:59:09)

0

5

если бы это было надо конкретной проге, одноразово, и вопроса не было бы
нужно получить адрес после лоада по номеру или по ид файла
CatchImage из датасекции работает как надо, это я сразу сделал, работает
так что в памяти лежит разжатый файл с головой
EncodeImage() это должно сработать, но так "неправильно", это костыль, или пока отказаться от этой затеи

0

6

newJS
почитай о функции _WinAPI_LoadImage, может в спецификации на msdn есть описание можно ли что либо из неё извлечь или это безвозвратная функция.

И описание на vsokovikov.narod.ru

Так как в описании сказано что BitMap, то любой рисунок становится растровым, то есть перекодируется из png/jpg в BitMap и получить из результата перекодирования уже ничего нельзя.

Отредактировано AZJIO (21.02.2022 18:39:56)

0

7

а в файлах не ВМР картинка просто упакована\сжата для уменьшения веса
картинка в памяти не перекодируется, она просто разворачивается\распаковывется чтобы иметь доступ к любому пикселю
а при сохранении картинка из памяти пакуется согласно нужному тебе расширению
так что в памяти лежит полноценная картинка с головой
чтобы лишить картинку головы, надо создать новую createimage, вот она будет без головы, нужную голову прицепит при сохранении

AZJIO написал(а):

почитай о функции

есть у меня всё это
спасибо за помощь

0

8

newJS написал(а):

не перекодируется, она просто разворачивается\распаковыветсяь

Разве это не одно и тоже? Разворачивается в BitMap, а заголовок BitMap`у не нужен, или нужен но только BitMap`ский, а не jpg.

Это определяется довольно просто. Возьми мой лаунчер и запусти его с фоном bmp или jpg. Если bmp неиндексированный 400 кб, а jpg 11 кб, в любом случае у тебя размер проги в памяти будет допустим на 1 Мб больше чем без фона (при условии что ширина и высота рисунков одинаковы), причём не важно какого фона bmp или jpg. Потому что оно преобразуется в BitMap и занимает как растровый рисунок, то есть все пикселы по строкам прописаны с указанием всех цветов.

newJS написал(а):

не перекодируется, она просто разворачивается\распаковыветсяь

это всё игра терминов. Не перекодируется не значит шифруется, также и распаковка можно по разному понимать, но суть одна если кодируется для уменьшение размера, то можно использовать термин упаковка/распаковка. Преобразуется, то есть не одно и тоже, и заголовок старый не нужен, он бесполезен, зачем его носить с собой. Старый заголовок нужен только чтобы использовать его для перекодировки в BitMap, чтобы перекодировщик понял с каким изображением он имеет дело.

Отредактировано AZJIO (22.02.2022 15:01:59)

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Нужно получить доступ к памяти после LoadImage()