begin
graphics := TGPGraphics.Create(PaintBox1.Canvas.Handle);
ResStr:= TResourceStream.Create(HInstance,'A1',RT_BITMAP);
Stream:= TStreamAdapter.Create(ResStr, soReference) as IStream;
Image := TGPImage.Create(Stream);
//Image := TGPImage.Create('A1.bmp'); - старый вариант, загрузка из файла
//с ним все работало
Label1.Caption:=IntTostr(Image.GetWidth);//Размер
Label2.Caption:=IntTostr(Image.GetHeight);//Размер
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
27-09-2008 04:44
от TStreamAdapter пришлось отказаться так как вылетает экцесс виалэйшн
Странно конечно... хотя я TMyStreamAdapter только с BMP и PNG проверял, может на GIF, что-то ещё вылезает.
Вот более-менее сносный рабочий код:
Можно чуточку попроще:
with TResourceStream.Create(hInstance,'IMG1','GIF') do try
OleCheck(CreateStreamOnHGlobal(0,True,Stream));
OleCheck(Stream.Write(Memory,Size,nil));
Image:=TGPBitmap.Create(Stream);
finally
Free;
end;
Вообщем принял все предложения, от TStreamAdapter пришлось отказаться так как вылетает экцесс виалэйшн.
Вот более-менее сносный рабочий код:
var
MainForm: TMainForm;
g: TGPGraphics;
bmp: TGPBitmap;
procedure TMainForm.FormCreate(Sender: TObject);
var
resHandle, resSize, hBuffer: Cardinal;
presData, pBuffer: pointer;
resIStream: IStream;
ERROR: Boolean;
begin
// получаем хэндл указанного ресурса
resHandle := FindResource(HInstance, 'IMG1', 'GIF');
if resHandle = 0 then ERROR := True;
// получаем размер ресурса
resSize := SizeofResource(HInstance, resHandle);
if resSize = 0 then ERROR := True;
// получаем указатель на первый байт ресурса
presData := LockResource(LoadResource(HInstance, resHandle));
if presData = nil then ERROR := True;
// выделяем необходимое количество байт в куче(heap) и получаем хэндл
hBuffer := GlobalAlloc(GMEM_MOVEABLE, resSize);
if hBuffer <> 0 then begin
// получаем указатель на выделенный блок памяти
pBuffer := GlobalLock(hBuffer);
if pBuffer <> nil then begin
// копируем ресурс в память
CopyMemory(pBuffer, presData, resSize);
// и создаем на его основе поток в памяти
if CreateStreamOnHGlobal(hBuffer, False, resIStream) = S_OK
then
// используем перегруженный метод создания изображения из потока
bmp := TGPBitmap.Create(resIStream);
end;
end;
if ERROR then Application.Messagebox('Не удалось загрузить изображения из ресурсов!',PChar(Caption),MB_ICONSTOP);
end;
Вообще существует известная проблема в TStreamAdapter, он не обнуляет некоторые поля TStatStg, а GDI+ это не любит (например при чтении PNG вообще исключение вываливается). Тут можно использовать своего наследника:
type
TMyStreamAdapter=class(TStreamAdapter)
public
function Stat(out statstg:TStatStg;grfStatFlag:LongInt):HRESULT;override; stdcall;
end;
function TMyStreamAdapter.Stat(out statstg:TStatStg;grfStatFlag:LongInt):HRESULT;
begin
Result:=S_OK;
try
if (@statstg<>nil) then
with statstg do begin
FillChar(statstg,SizeOf(statstg),0);
dwType:=STGTY_STREAM;
cbSize:=Stream.Size;
grfLocksSupported:=LOCK_WRITE;
end;
except
Result:=E_UNEXPECTED;
end;
end;
Так же можно использовать в качестве промежуточного хранилища IStream созданный с помощью CreateStreamOnHGlobal.
Но в данном конкретном случае проблема не в потоках и адаптерах, а непонимании того как хранятся стандартные ресурсы, ну и нежелании читать справку по GDI+:
Во первых ресурсы типа RT_BITMAP и BMP-файлы это две большие разницы и глупо подсовывать такой ресурс в качестве обычного потока. Так что проблему можно решить просто заменив тип ресурса на какой нибудь "MYBITMAP" (по размеру, он будет чуточку больше стандартного).
Во вторых у TGPImage есть наследник TGPBitmap с методом "constructor Create(hInstance: HMODULE; bitmapName: WideString); reintroduce; overload;", так что достаточно было написать всего одну строчку "Image:=TGPBitmap.Create(HInstance,'A1');" и всё.
Думаю, что кому-то это, возможно, в облегчит жизнь ! :-)
Спасиб, собрат по разуму!
Пригодились твои коды, а то приходилось через временные файлы битмапы загружать.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.