Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
2-1150844721
learner
2006-06-21 03:05
2006.07.09
Обмен данными между консольными приложениями


6-1141646556
quantum
2006-03-06 15:02
2006.07.09
Картинка и TWebbrowser


2-1150777702
Rubey
2006-06-20 08:28
2006.07.09
Связь таблиц при скроллинге


2-1150983945
AlexanderMS
2006-06-22 17:45
2006.07.09
Как работать с ресурсами в Delphi?


2-1150535185
KLAUS
2006-06-17 13:06
2006.07.09
Генерация пароля





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский