Форум: "Media";
Текущий архив: 2006.07.09;
Скачать: [xml.tar.bz2];
ВнизВывод большого изображения (Gb) Найти похожие ветки
← →
hgd (2005-12-16 20:59) [0]Подскажите, мне надо выводить большое изображение (bmp весит 1 Gb) и выводить надо со 100% размером. Тоесть если картинка 10000 на 10000, то на экране 800 на 600 надо вывести кусок. Как это сделать и можно ли предусмотреть скроллинг изображения?
← →
TUser © (2005-12-16 21:10) [1]TScrollBox
← →
Kolan © (2005-12-16 21:11) [2]ScrollBox не подойдет?
← →
Джо © (2005-12-16 21:11) [3]Боюсь, что стандартными средствами изображение такого размера не вывести. Я имею все, что построено на TCanvas и TBitmap. Впрочем, практика - критерий истины.
← →
Джо © (2005-12-16 21:12) [4]
> Я имею все
Я имею в виду все
← →
Eraser © (2005-12-16 21:30) [5]
> Джо © (16.12.05 21:11) [3]
> Я имею все, что построено на TCanvas и TBitmap.
Ну TCanvas в любом случае использовать прийдётся, ну или по крайней мере HDC )
> hgd (16.12.05 20:59)
На torry.net по-моему есть компоненты для работы с большими граф. файлами.
← →
Andy BitOff © (2005-12-16 21:39) [6]На основании своей практики могу посоветовать GDIPlus для вывода. Я выводил jpg 19 метров, 13500 по ширине и 8500 по высоте - доли секуды.
http://msdn.microsoft.com/library/en-us/gdicpp/GDIPlus/GDIPlus.asp
← →
Джо © (2005-12-16 21:43) [7]Присоединяюсь к совету попробовать GDI+.
> [5] Eraser © (16.12.05 21:30)
У меня тут уже в голове после сегодняшней запарки перепуталось все. Конечно, я имел в виду TBitmap, собственно из-за его "out of resources" ^)
← →
GuAV © (2005-12-16 21:54) [8]Если загрузится в TBitmap, то
ScrollBox + PaintBox, у PaintBox в OnDraw юзать ClipRect, делая туда BrushCopy(R, FBitmap, SrcRect, clNone);, или не туда а во временный Bitmap по размерам ClipRect, если "кэширование" нужно.
Я так делал, хотя мои картинки много меньше.
← →
Германн © (2005-12-17 01:27) [9]Не специалист, но имхо, смахивает на задачу ГИС. Так может покопать именно в эту сторону?
← →
Separator © (2005-12-17 04:57) [10]Выводи почастям, а при прокрутке подгружай нужные части
← →
hgd (2005-12-17 10:36) [11]да это действительно задача ГИС, может есть какие-нибудь компоненты?
← →
Германн © (2005-12-18 02:26) [12]
> hgd (17.12.05 10:36) [11]
>
> да это действительно задача ГИС, может есть какие-нибудь
> компоненты?
Был бы тут ShaggiDoc он бы ответил.
Вроде бы, "просто компонента" нет.
Но ведь есть Яндекс, Гугль и т.п. Да пребудет с ними... Ищи там.
← →
PAVIA © (2005-12-18 14:03) [13]Сам напиши.
← →
wicked © (2005-12-18 20:47) [14]вставлю свои 3 коп.....
учитывая, что это bmp, могу посоветовать MMF + StretchDIBits...
с помощью 1-го - отображаем файлик в память (думаю, 1 Гб отобразит), с помощью 2-го - рисуем нужный кусок на экране....
такие вот домыслы, я бы с этого начинал...
← →
miek © (2005-12-19 09:24) [15]MMF безусловно сработает - создать дибсекцию на отображении и вперед, хоть BitBlt, хоть StretchBlt..
← →
WondeRu © (2005-12-19 11:54) [16]wicked © (18.12.05 20:47) [14]
с помощью 1-го - отображаем файлик в память (думаю, 1 Гб отобразит),
фига се....
Автору советую читать напрямую из файла по кусочкам, формат файла .bmp очень простой.
← →
wicked © (2005-12-19 12:38) [17]> WondeRu © (19.12.05 11:54) [16]
> фига се....
когда я экспериментировал с MMF, то файлы по 700 Мб (фильм, 1 шт) отлично отображались в память, коей было всего 256 Мб.....
← →
wicked © (2005-12-19 12:40) [18]
> MMF безусловно сработает - создать дибсекцию на отображении
> и вперед, хоть BitBlt, хоть StretchBlt..
можно без дибсекции - см. StretchDIBits....
← →
Ryan Dickinson (2006-01-19 16:49) [19]Удалено модератором
← →
имя (2006-01-19 16:51) [20]Удалено модератором
← →
0bsid © (2006-01-25 15:30) [21]я пользуюсь компонентой Graphics32. изображение 500 мб отображается на ура.
← →
имя (2006-01-25 17:11) [22]Удалено модератором
← →
Universe © (2006-01-28 16:04) [23]По подробнее пример использования MMF + StretchDIBits можно посмотреть?
← →
wicked © (2006-01-29 22:39) [24]
> По подробнее пример использования MMF + StretchDIBits можно
> посмотреть?
1) класс, создающий MMF... наследник TCustomMemoryStream...unit MMapStream;
interface
uses Windows, SysUtils, Classes;
const
def_Granularity = (512 * 1024);
type
TMemoryMapStream = class(TCustomMemoryStream)
protected
fRealSize: integer;
fGranularity: integer;
fFile: THandle;
fMemMap: THandle;
fReadOnly: boolean;
procedure SetSize(const NewSize: int64); overload; override;
procedure SetGranularity(value: integer); virtual;
procedure OpenMMap; virtual;
procedure CloseMMap; virtual;
procedure Map; virtual;
procedure UnMap; virtual;
procedure doPack(reopen: boolean); virtual;
procedure SetEOF(pos: integer); virtual;
public
constructor Create(const AFileName: string; RequestReadOnly: boolean = false; AGranularity: integer = def_Granularity);
destructor Destroy; override;
procedure Clear;
procedure SetSize(NewSize: integer); overload; override;
function Write(const Buffer; Count: longint): longint; override;
procedure LoadFromFile(const FileName: string); virtual;
procedure LoadFromStream(Stream: TStream); virtual;
procedure Pack; virtual;
property Granularity: integer read fGranularity write SetGranularity;
property ReadOnly: boolean read fReadOnly;
end;
implementation
const
min_size = 1024;
constructor TMemoryMapStream.Create(const AFileName: string; RequestReadOnly: boolean = false; AGranularity: integer = def_Granularity);
var filesize: integer;
begin
inherited Create;
SetPointer(nil, 0);
fRealSize:= 0;
SetGranularity(AGranularity);
fFile := 0;
fMemMap := 0;
fReadOnly := false;
try
if not RequestReadOnly then
fFile := CreateFile(
PChar(AFileName), // name
GENERIC_READ or GENERIC_WRITE, // desired access
FILE_SHARE_READ, // share mode (share read)
nil, // security attributes
OPEN_ALWAYS, // OPEN_EXISTING, // creation disposition
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_RANDOM_ACCESS, // flags and attributes
0{nil}); // template file
if (fFile = INVALID_HANDLE_VALUE) or RequestReadOnly then begin
fFile := CreateFile(
PChar(AFileName), // name
GENERIC_READ, // desired access
FILE_SHARE_READ, // share mode (share read)
nil, // security attributes
OPEN_EXISTING, // creation disposition
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_RANDOM_ACCESS, // flags and attributes
0{nil}); // template file
if fFile = INVALID_HANDLE_VALUE then raise Exception.Create("could not open the file " + AFileName);
fReadOnly := true;
end;
filesize := GetFileSize(fFile, nil);
if filesize = 0 then SetEOF(min_size);
OpenMMap;
except
CloseMMap;
if (fFile <> 0) and (fFile <> INVALID_HANDLE_VALUE) then CloseHandle(fFile);
raise;
end;
Seek(0, soFromBeginning);
end;
destructor TMemoryMapStream.Destroy;
begin
if fFile <> 0 then begin
doPack(false);
CloseHandle(fFile);
end;
end;
procedure TMemoryMapStream.OpenMMap;
begin
if fFile <> 0 then begin
if fReadOnly then fMemMap := CreateFileMapping(fFile, nil, PAGE_READONLY or SEC_COMMIT, 0, 0, nil)
else fMemMap := CreateFileMapping(fFile, nil, PAGE_READWRITE or SEC_COMMIT, 0, 0, nil);
if fMemMap = 0 then raise Exception.Create("could not create memory map of file");
Map;
end;
end;
procedure TMemoryMapStream.CloseMMap;
begin
if fMemMap <> 0 then begin
UnMap;
CloseHandle(fMemMap);
end;
end;
procedure TMemoryMapStream.Map;
var p: pointer;
filesize: integer;
begin
SetPointer(nil, 0);
if fReadOnly then
p := MapViewOfFile(fMemMap, FILE_MAP_READ, 0, 0, 0)
else
p := MapViewOfFile(fMemMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if p = nil then raise Exception.Create("could not read file");
filesize := GetFileSize(fFile, nil);
fRealSize := filesize;
SetPointer(p, filesize);
Position := 0;
end;
procedure TMemoryMapStream.UnMap;
begin
if Memory <> nil then begin
if not fReadOnly then FlushViewOfFile(Memory, 0);
UnmapViewOfFile(Memory);
end;
end;
procedure TMemoryMapStream.doPack(reopen: boolean);
begin
CloseMMap;
try
SetEOF(Size);
finally
if reopen then OpenMMap;
end;
end;
procedure TMemoryMapStream.SetEOF(pos: integer);
begin
if fReadOnly then exit;
if SetFilePointer(fFile, pos, nil, FILE_BEGIN) = DWORD(-1) then // !!! INVALID_SET_FILE_POINTER
raise Exception.Create("could not resize file");
SetEndOfFile(fFile);
end;
//---------------------------------------------------------------------------
procedure TMemoryMapStream.SetSize(const NewSize: int64);
begin
SetSize(integer(NewSize));
end;
procedure TMemoryMapStream.SetGranularity(value: integer);
begin
if value = fGranularity then exit;
fGranularity := value;
if fGranularity < min_size then fGranularity := min_size;
end;
procedure TMemoryMapStream.Clear;
begin
SetSize(min_size);
doPack(true);
ZeroMemory(Memory, min_size);
end;
procedure TMemoryMapStream.SetSize(NewSize: integer);
var mult: integer;
begin
if NewSize = Size then exit;
if (fFile <> 0) and not fReadOnly then begin
if NewSize > fRealSize then begin
CloseMMap;
mult := (NewSize - fRealSize) div fGranularity;
if ((NewSize - fRealSize) mod fGranularity) > 0 then
fRealSize := fRealSize + ((mult + 1) * fGranularity)
else
fRealSize := fRealSize + (mult * fGranularity);
SetEOF(fRealSize);
OpenMMap;
SetPointer(Memory, NewSize);
end
else SetPointer(Memory, NewSize);
end;
end;
function TMemoryMapStream.Write(const Buffer; Count: longint): longint;
var pos: longint;
begin
pos := Position;
if (pos < 0) or (Count <= 0) or fReadOnly then begin
result := 0;
exit;
end;
if (pos + Count) > Size then SetSize(pos + Count);
System.Move(Buffer, (pointer(longint(Memory) + pos))^, Count);
pos := pos + Count;
Position := pos;
Result := Count;
end;
procedure TMemoryMapStream.LoadFromFile(const FileName: string);
var f: TFileStream;
begin
f := TFileStream.Create(FileName, fmOpenRead);
try
LoadFromStream(f);
finally
f.Free;
end;
end;
procedure TMemoryMapStream.LoadFromStream(Stream: TStream);
var sz: integer;
begin
if fReadOnly then exit;
sz := Stream.Size;
SetSize(sz);
Stream.Read(Memory^, sz);
Seek(0, soFromBeginning);
end;
procedure TMemoryMapStream.Pack;
begin
doPack(true);
end;
end.
не идеален, но свои функции исполняет...
← →
wicked © (2006-01-29 22:39) [25]
> По подробнее пример использования MMF + StretchDIBits можно
> посмотреть?
2) вывод изображения с помощью StretchDIBits (на билдере - перевести на паскаль - задание на дом)void __fastcall PaintStretchedDIB(void * srcdata, TRect& srcrect, HDC dstdc, TRect& dstrect)
{
LPBITMAPFILEHEADER bfh = (LPBITMAPFILEHEADER) srcdata;
LPBITMAPINFO bi = (LPBITMAPINFO)((LPBYTE)srcdata + sizeof(BITMAPFILEHEADER));
StretchDIBits(dstdc, dstrect.left, dstrect.top, dstrect.Width(), dstrect.Height(),
srcrect.left, srcrect.top, srcrect.Width(), srcrect.Height(),
((LPBYTE)srcdata + bfh->bfOffBits), bi, DIB_RGB_COLORS, SRCCOPY);
}
использовать:
PaintStretchedDIB(MemoryMapStream.Memory, Rect(0, 0, 100, 100), dest_dc, Rect(0, 0, 100, 100)) - рисует из MMF-а кусок размером 100x100 пикселей...
← →
wicked © (2006-01-29 22:41) [26]ЗЫ если нужно рисовать весь ДИБ, рекомендую подшаманить PaintStretchedDIB - вместо использования srcrect нужно использовать члены структуры LPBITMAPINFO - переменная bi....
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2006.07.09;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.008 c