Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.04.2010, 16:55   #11
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Цитата:
по колено в Windows API
Я пока только по щиколотки и уже открыл для себя пару десятков более быстрых и качественных методов сделать какую-либо вещь.
Цитата:
мелкомягкую теорию проштудировать
Есть ли электронные книги именно по этой теме?
Цитата:
после SelectObject и до DeleteDC
используем временный контекст(M)
пока я разбираюсь, не могли бы пример подсунуть с узнаванием пиксела и его заменой при помощи Set? И Get\SetPixel - это быстрые методы или нет? Если нет, то что быстрее?
Цитата:
это установка изображения компоненту, но я бы сказал, не совсем все таки рисование.
так, а что быстрее? Просто буду общаться с достаточно большим изображением (соразмерно размеру экрана). Я вот, что заметил - при рисовании через контекст при репаинте придется рисовать заново, а Send устанавливает картинку на века. Т.е. не лучше ли будет рисовать на временном HBITMAP`е и выводить его целиком, чем обновлять картинку "рисованием" каждый репаинт?
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 29.04.2010, 18:09   #12
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
а Send устанавливает картинку на века.
просто рисуют за вас

быстрее Get/SetDIBits(как ScanLine по сути)

пример позже могу написать разве что(сейчас настроения вообще нет)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 29.04.2010, 21:40   #13
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

А я TBitmap.ScanLine пользуюсь, к скорости нареканий нет, проверено много раз уже, оч. удобная и быстрая штука, на фоне нагрузки от остальных алгоритмов обработки (обычно не просто ведь отображение делаешь, а какой-то прикладной смысл есть) он даже и не ощущается, быстро работает даже на оч. больших изображениях. Под капотом у него скорее всего да, эта парочка - Get/SetDIBits. Про Canvas.Draw могу сказать тоже самое, замерял, никакой разницы по скорости в сравнении с BitBlt. API просто больше возможностей предоставляет, в VCL представлены лишь некоторые из них, когда их хватает - хорошо, когда нет - приходится лезть в АПИ.

Цитата:
пока я разбираюсь, не могли бы пример подсунуть с узнаванием пиксела и его заменой
Если нет идеологических препятствий, используй ScanLine, он способен быстро это сделать. Считываешь его в PByteArray, в зависимости от пиксель формата картинки полученная строка интерпретируется по разному, при 24 бит цвете, там идет строка пикселей в BGR формате. Читаешь байты по три штуки отдельно, или в TRGBTriple загоняешь, как удобнее. Изменяешь, и если больше ничего не нужно, прерываешь цикл. Затем остается обновить битмап (а можно не весь, а его нужную часть) на экране.

Вот, для примера, из одной моей программы кусок
Код:
procedure BlackToGray(bm: TBitmap; GrayValue: byte);
var
  y: Integer;
  p: PByteArray;
  x: Integer;
  clr: cardinal;
begin
  bm.PixelFormat:=pf24bit;
  for y := 0 to bm.Height - 1 do begin
    p:=bm.ScanLine[y];
    for x := 0 to bm.Width - 1 do begin
      clr:=RGB(p[x*3+2], p[x*3+1], p[x*3]);
      if clr = 1 then begin
        p[x*3]:=GrayValue;
        p[x*3+1]:=GrayValue;
        p[x*3+2]:=GrayValue;
      end;
      if clr = clWhite - 1 then begin //restore white color
        p[x*3]:=255;
        p[x*3+1]:=255;
        p[x*3+2]:=255;
      end;
    end;
  end;
end;
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 29.04.2010 в 21:54.
mutabor вне форума Ответить с цитированием
Старый 29.04.2010, 22:03   #14
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Цитата:
Если нет идеологических препятствий
Да вот в том, то и дело, что религия не позволяет какой-л. модуль подключать Вот и пишу ТОЛЬКО средствами апи.

P.S. Да, ударился.
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 08.05.2010, 17:03   #15
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Так, назрел вопрос:
Как "ужимать" картинку, которая в HBitMAP? Например была 800 х 600, а сделать 640 х 480. Не обрезанием, а масштабированием.
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 08.05.2010, 17:22   #16
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

1. Заголовки BITMAP описаны в windows.h/.pas и т.п.
2. Открываете файл читаете заголовок
3. Получаете width, height, pixelsize и т.п. + смещение в файле на биты (само изображение)
4. CreateDIBSection - где указываете размеры, биты вообще все данные которые получили из п. 3
5. Теперь у вас есть, HDC + HBITMAP + Scan0, и теперь у вас доступ к вашему BITMAP на прямую Scan0, через GDI/GDI+ HDC.
6. Алгоритмы и функции для масштабирования море, как прямое масштабирование по пиксельно, так и функции GDI подобные StrechBlt.

Еще вопросы ?
BOBAH13 вне форума Ответить с цитированием
Старый 08.05.2010, 17:35   #17
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

1) Заголовки Bitmap`а имеются в виду эти:?
Код:
typedef struct tagBITMAPFILEHEADER 
{ 
  WORD    bfType; 
  DWORD   bfSize; 
  WORD    bfReserved1; 
  WORD    bfReserved2; 
  DWORD   bfOffBits; 
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
Код:
typedef struct { 
  DWORD        bV5Size; 
  LONG         bV5Width; 
  LONG         bV5Height; 
  WORD         bV5Planes; 
  WORD         bV5BitCount; 
  DWORD        bV5Compression; 
  DWORD        bV5SizeImage; 
  LONG         bV5XPelsPerMeter; 
  LONG         bV5YPelsPerMeter; 
  DWORD        bV5ClrUsed; 
  DWORD        bV5ClrImportant; 
  DWORD        bV5RedMask; 
  DWORD        bV5GreenMask; 
  DWORD        bV5BlueMask; 
  DWORD        bV5AlphaMask; 
  DWORD        bV5CSType; 
  CIEXYZTRIPLE bV5Endpoints; 
  DWORD        bV5GammaRed; 
  DWORD        bV5GammaGreen; 
  DWORD        bV5GammaBlue; 
  DWORD        bV5Intent; 
  DWORD        bV5ProfileData; 
  DWORD        bV5ProfileSize; 
  DWORD        bV5Reserved; 
} BITMAPV5HEADER, *PBITMAPV5HEADER;
2) Насколько я понимаю через file of byte?
3) Это ясно.
4) Вот тут не понятно, как её юзать:
Код:
HBITMAP CreateDIBSection(
  __in   HDC hdc,
  __in   const BITMAPINFO *pbmi,
  __in   UINT iUsage,
  __out  VOID **ppvBits,
  __in   HANDLE hSection,
  __in   DWORD dwOffset
);
Цитата:
hdc [in]

A handle to a device context. If the value of iUsage is DIB_PAL_COLORS, the function uses this device context's logical palette to initialize the DIB colors.
Дать ей пустой, только что созданный?
Цитата:
pbmi [in]

A pointer to a BITMAPINFO structure that specifies various attributes of the DIB, including the bitmap dimensions and colors.
на что указатель? О_о
Цитата:
ppvBits [out]

A pointer to a variable that receives a pointer to the location of the DIB bit values.
Указатель, который принимает указатель?..
Цитата:
hSection [in]

A handle to a file-mapping object that the function will use to create the DIB. This parameter can be NULL.

If hSection is not NULL, it must be a handle to a file-mapping object created by calling the CreateFileMapping function with the PAGE_READWRITE or PAGE_WRITECOPY flag. Read-only DIB sections are not supported. Handles created by other means will cause CreateDIBSection to fail.

If hSection is not NULL, the CreateDIBSection function locates the bitmap bit values at offset dwOffset in the file-mapping object referred to by hSection. An application can later retrieve the hSection handle by calling the GetObject function with the HBITMAP returned by CreateDIBSection.

If hSection is NULL, the system allocates memory for the DIB. In this case, the CreateDIBSection function ignores the dwOffset parameter. An application cannot later obtain a handle to this memory. The dshSection member of the DIBSECTION structure filled in by calling the GetObject function will be NULL.
Мало, что понял.
Цитата:
dwOffset [in]

The offset from the beginning of the file-mapping object referenced by hSection where storage for the bitmap bit values is to begin. This value is ignored if hSection is NULL. The bitmap bit values are aligned on doubleword boundaries, so dwOffset must be a multiple of the size of a DWORD.
Уж не bfOffBits; из FILEHEADER?

5) Хотелось бы увидеть сие в действии.
6) Тут без проблем.
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 08.05.2010, 17:41   #18
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Выдернул из своего кода (думаю то что на С++ это не проблема)
Код:
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // думаю ясно что есть bi :) BITMAPINFO *bi;
	bi->bmiHeader.biBitCount = 32; // мне нужно было только ARGB, в вашем случае ищите в заголовках
	bi->bmiHeader.biCompression = BI_RGB;
	bi->bmiHeader.biHeight = height;
	bi->bmiHeader.biWidth = width;
	bi->bmiHeader.biPlanes = 1;
	bi->bmiHeader.biSizeImage = bi->bmiHeader.biWidth * bi->bmiHeader.biHeight * 4; // почему 4 думаю ясно, 4 = 32 бита

	bitmap = CreateDIBSection(0, bi, DIB_RGB_COLORS, (void**)&scan0, 0, 0); // scan0 - void*, ну или тот же pointer
Как связать HDC?
Код:
dc = CreateCompatibleDC(0);
oldBitmap = (HBITMAP)SelectObject(dc, bitmap);
При удалении объекта
Код:
SelectObject(dc, oldBitmap);
DeleteObject(bitmap);
Вроде простенько
BOBAH13 вне форума Ответить с цитированием
Старый 08.05.2010, 18:52   #19
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Цитата:
(думаю то что на С++ это не проблема)
Цитата:
(void**)&scan0
пожалейте мой мозг, переведите на delphi... Пожа-а-а-алуйста

Вот, что накропал. Поможьте сделать загрузку из *.bmp и рисование на Image (Handle от Image прилагается).

Код:
Procedure LoadBitmapFromFile(MainDC : HDC);
  Var
   UseDC    : HDC;
   BMI      : BITMAPINFO;
   HBit     : HBitMap;
   PointDIB : Pointer;
  Begin
   UseDC := CreateCompatibleDC(MainDC);
   ZeroMemory(@BMI, SizeOf(BITMAPINFO));
   BMI.bmiHeader.biSize := SizeOf(BITMAPINFOHEADER);
   BMI.bmiHeader.biWidth := 800;
   BMI.bmiHeader.biHeight := 600;
   BMI.bmiHeader.biPlanes := 1;
   BMI.bmiHeader.biBitCount := 24;
   BMI.bmiHeader.biCompression := BI_RGB;
   BMI.bmiHeader.biSizeImage := 800 * 600 * 3;
   HBit := CreateDIBSection(UseDC, BMI, DIB_RGB_COLORS, PointDIB, 0, 0);
   SelectObject(UseDC, HBit);

   DeleteObject(HBit);
   DeleteDC(UseDC);
  End;
P.S. Кажись начинаю что-то просветлять в голове.

Плюнул на DIB, сделал как во втором посте. Редактировать изображение теперь как в теме "DLL библиотека эффектов"?

Код:
Var
   HSplash : HBitMap;
   Bit     : BitMap;
   Loc     : HDC;
   Main    : HDC;
  Begin
   HSplash := LoadImage(GetModuleHandle(Nil), PChar(CurDir + '\Resource\Interface\Splash\Splash.bmp'), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
   Main := GetDC(Application.FRMMain.IMGMain.Handle);
   Loc := CreateCompatibleDC(Main);
   SelectObject(Loc, HSplash);
   GetObject(HSplash, SizeOf(BITMAP), @Bit);
   BitBlt(Main, 0, 0, Bit.bmWidth, Bit.bmHeight, Loc, 0, 0, SRCCOPY);
   DeleteDC(Loc);
   DeleteObject(HSplash);
/r/ пояснение, как редактировать.
Код:
Procedure FVFL_ConvertToBW(Handle: HBITMAP); StdCall;
Var
 X, Y: Integer;
 C: Byte;
 BMP: BITMAP;
 P1, P2: PRGBTriple;
Begin
 Windows.GetObject(Handle, SizeOf(Bmp), @BMP);
 P1 := BMP.bmBits;
 If BMP.bmBitsPixel = 24 Then
      For Y := 0 To BMP.bmHeight - 1 Do
            Begin
             P2 := P1;
             For X := 0 To BMP.bmWidth - 1 Do
                  Begin
                   C:=(P2.RGBTRed + P2.RGBTGreen + P2.RGBTBlue) Div 3;
                   P2.rgbtRed   := C;
                   P2.rgbtGreen := C;
                   P2.rgbtBlue  := C;
                   Inc(P2);
                  End;
             Pointer(P1) := Pointer(Integer(P1) + BMP.bmWidthBytes);
            End
 Else
  MessageBox(0, 'Library error - 0x00', 'Error', MB_OK);
End;
Так?
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ

Последний раз редактировалось Stilet; 29.06.2010 в 10:43.
Alex Cones вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
где можно скачать corel draw x4 Полный ноль Помощь студентам 2 24.02.2011 11:06
Hbitmap из png zumm Мультимедиа в Delphi 1 27.03.2010 20:55
Рисование картинки методом Draw Nazar1994 Общие вопросы Delphi 2 21.11.2009 01:57
Работа для знающих corel draw Sanja Фриланс 2 22.10.2008 07:08
Corel Draw - рисунки после редактирования здорово увеличиваются Viteef Свободное общение 8 19.02.2008 09:16