Drukowanie bitmapy

problemy z tworzeniem aplikacji graficznych oraz audio i wideo

Re: Drukowanie bitmapy

Nowy postprzez duf » sobota, 12 czerwca 2010, 10:54

polymorphism napisał(a):Spróbuj może metody, o której pisałem wcześniej. Z dużym prawdopodobieństwem zadziała, a i kod będzie prostszy.

Nie wiem co masz na myśli.
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie bitmapy

Nowy postprzez polymorphism » sobota, 12 czerwca 2010, 11:27

Pisałem żebyś użył funkcji SetDIBitsToDevice lub StretchDIBits, ale zamiast bawić się z tworzeniem bitmap w WinAPI i kopiowaniem ich, od razu kopiował z TBitmap (w której składasz wydruk) do kontekstu drukarki. Dostęp do pamięci bitmapy będziesz miał przez właściwość ScanLine.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie bitmapy

Nowy postprzez duf » sobota, 12 czerwca 2010, 12:53

polymorphism napisał(a):Pisałem żebyś użył funkcji SetDIBitsToDevice lub StretchDIBits, ale zamiast bawić się z tworzeniem bitmap w WinAPI i kopiowaniem ich, od razu kopiował z TBitmap (w której składasz wydruk) do kontekstu drukarki. Dostęp do pamięci bitmapy będziesz miał przez właściwość ScanLine.

Dobra Jestem przerażony ilością parametrów z których może dwa udałoby mi się wstawić. Musiałbym zacząć drążyć ten temat co zajęłoby mi znowu mnóstwo czasu. Gdybym mógł bawić się builder`em 24 godziny na dobę na pewno bym w to wszedł. Jak na razie muszę wybierać pomiędzy informacjami ogólnymi a szczegółowymi na niekorzyść tych ostatnich.
W najgorszym razie wrócę do pomysłu z TImage, z którym mam pewne doświadczenie i zachowuje się przewidywalnie. Wiem, że nie jest to
artyzm programowania.
Jak możesz i masz ochotę to napisz jak użyć tych parametrów i ScanLine.
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie bitmapy

Nowy postprzez duf » sobota, 12 czerwca 2010, 14:30

polymorphism napisał(a):Ech, duf. Przecież te błędy są banalne, wystarczy przeczytać ze zrozumieniem ich treść. (tylko nie pisz, że jesteś początkującym, bo już trochę na tych forach siedzisz, więc pewne rzeczy powinieneś wiedzieć)

[BCC32 Error] File1.cpp(158): E2034 Cannot convert 'void *' to 'HBITMAP__ *'

Zastosuj rzutowanie...

[BCC32 Error] File1.cpp(169): E2379 Statement missing ;

A ten '×' w 0x300 to na pewno 'x'?

[BCC32 Error] File1.cpp(252): E2268 Call to undefined function 'floor'

Nie taki undefined -> floor.

Zrobione. Ten 'x' to 'X'
Jak użyć tej funkcji?
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie bitmapy

Nowy postprzez polymorphism » sobota, 12 czerwca 2010, 15:26

O którą funkcję pytasz? Jeśli o tę, którą podał baron, to nie rozumiem, co tam jest niejasnego. Cztery parametry, których nazwy są dość wymowne... co ja piszę, przecież jest tam opis tych parametrów.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie bitmapy

Nowy postprzez Cyfrowy Baron » sobota, 12 czerwca 2010, 15:35

Funkcja floor znajduje się w bibliotece math.h, a więc:

Kod: Zaznacz cały
#include <math.h>


Co do tej funkcji ze strony http://raz-soft.com/c-builder/printing-a-tbitmap-with-stretchdibits/, to działa po drobnych poprawkach:

poprawiony kod ze strony http://raz-soft.com/
Kod: Zaznacz cały


sposób wywołania:

Kod: Zaznacz cały
void __fastcall PrintImage(TCanvas *PrinterCanvas,int pX,int pY,
        Graphics::TBitmap *TheBitmap)
{
  HDC h_dc = TheBitmap->Canvas->Handle;
  int bmp_w = TheBitmap->Width, bmp_h = TheBitmap->Height;

  HDC h_mem_dc = ::CreateCompatibleDC (h_dc);
  HBITMAP h_mem_bmp = ::CreateCompatibleBitmap (h_dc, bmp_w, bmp_h);
  HBITMAP h_old_bmp = ::SelectObject (h_mem_dc, h_mem_bmp);

  bool is_pal_dev = false;
  LOGPALETTE *pal;
  HPALETTE h_pal, h_old_pal;

  if(::GetDeviceCaps (TheBitmap->Canvas->Handle, RASTERCAPS) & RC_PALETTE)
  {
   pal = static_cast<LOGPALETTE *>(malloc(sizeof (LOGPALETTE) +
                                              (sizeof (PALETTEENTRY) * 256)));

   memset(pal, 0, sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256));
   pal->palVersion = 0x300;
   pal->palNumEntries = ::GetSystemPaletteEntries(TheBitmap->Canvas->Handle, 0, 256, pal->palPalEntry);

   if(pal->palNumEntries != 0)
   {
    h_pal = ::CreatePalette (pal);
    h_old_pal = ::SelectPalette (h_mem_dc, h_pal, false);
    is_pal_dev = true;
   }
   else
   {
    free(pal);
   }
  }

  ::BitBlt (h_mem_dc, 0, 0, bmp_w, bmp_h, h_dc, 0, 0, SRCCOPY);

  if (is_pal_dev)
  {
   ::SelectPalette (h_mem_dc, h_old_pal, false);
   ::DeleteObject (h_pal);
  }

  ::SelectObject (h_mem_dc, h_old_bmp);
  ::DeleteDC (h_mem_dc);

  HANDLE h_bmp_info = ::GlobalAlloc(GHND, sizeof (BITMAPINFO) +
                                     (sizeof (RGBQUAD) * 256));
  BITMAPINFO* bmp_info = static_cast<BITMAPINFO *>(::GlobalLock(h_bmp_info));

  memset(bmp_info, NULL, sizeof (BITMAPINFO) + (sizeof (RGBQUAD) * 255));
  bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  bmp_info->bmiHeader.biPlanes = 1;
  bmp_info->bmiHeader.biBitCount = 8;//or 8
  bmp_info->bmiHeader.biWidth = bmp_w;
  bmp_info->bmiHeader.biHeight = bmp_h;
  bmp_info->bmiHeader.biCompression = BI_RGB;

  ::GetDIBits (h_dc, h_mem_bmp, 0, bmp_h, NULL, bmp_info, DIB_RGB_COLORS);

  HANDLE h_bits = GlobalAlloc (GHND, bmp_info->bmiHeader.biSizeImage);
  void *bits = ::GlobalLock (h_bits);

  ::GetDIBits (h_dc, h_mem_bmp, 0, bmp_h, bits, bmp_info, DIB_RGB_COLORS);

  if(is_pal_dev)
  {
   for (int i = 0; i < pal->palNumEntries; i++)
   {
    bmp_info->bmiColors[i].rgbRed = pal->palPalEntry[i].peRed;
    bmp_info->bmiColors[i].rgbGreen = pal->palPalEntry[i].peGreen;
    bmp_info->bmiColors[i].rgbBlue = pal->palPalEntry[i].peBlue;
   }
   free (pal);
  }

  is_pal_dev = false;
  if( ::GetDeviceCaps (h_dc, RASTERCAPS) & RC_PALETTE)
  {
   pal = static_cast<LOGPALETTE *>(malloc(sizeof (LOGPALETTE) +
                                            (sizeof (PALETTEENTRY) * 256)));
   memset(pal, 0, sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * 256));
   pal->palVersion = 0x300;
   pal->palNumEntries = 256;

   for (int i = 0; pal->palNumEntries; i++)
   {
    pal->palPalEntry[i].peRed = bmp_info->bmiColors[i].rgbRed;
    pal->palPalEntry[i].peGreen = bmp_info->bmiColors[i].rgbGreen;
    pal->palPalEntry[i].peBlue = bmp_info->bmiColors[i].rgbBlue;
   }

   h_pal = CreatePalette(pal);
   free (pal);
   h_old_pal = SelectPalette(PrinterCanvas->Handle, h_pal, false);
   is_pal_dev = true;
  }

  int PrnXRes = GetDeviceCaps(PrinterCanvas->Handle, LOGPIXELSX);
  int PrnYRes = GetDeviceCaps(PrinterCanvas->Handle, LOGPIXELSY);
  bmp_w = floor(((double)TheBitmap->Width / (double)Screen->PixelsPerInch) *
                                                         (double)PrnXRes);
  bmp_h = floor(((double)TheBitmap->Height / (double)Screen->PixelsPerInch) *
                                                           (double)PrnYRes);

  StretchDIBits(PrinterCanvas->Handle, pX, pY, bmp_w, bmp_h,
                0, 0, TheBitmap->Width, TheBitmap->Height, bits,bmp_info,
                DIB_RGB_COLORS, SRCCOPY);

  ::DeleteObject(h_mem_bmp);
  if(is_pal_dev)
  {
   ::SelectObject (PrinterCanvas->Handle, h_old_pal);
   ::DeleteObject (h_pal);
  }

  ::GlobalUnlock (bits);
  ::GlobalFree (h_bits);
  ::GlobalUnlock (bmp_info);
  ::GlobalFree (h_bmp_info);
}


W tej funkcji grafika jest drukowana nie na całej stronie płótna drukarki, lecz w oparciu o wymiary obrazka. Kluczem do zmiany sposobu wypełniania kartki grafiką jest ten element funkcji PrintImage:

Kod: Zaznacz cały
  StretchDIBits(PrinterCanvas->Handle, pX, pY, bmp_w, bmp_h,
                0, 0, TheBitmap->Width, TheBitmap->Height, bits,bmp_info,
                DIB_RGB_COLORS, SRCCOPY);  


Czyli jest to dokładnie to o czym wspomniał polymorphism.

Funkcja sprawdza rozdzielczość drukarki i skaluje grafikę dostosowując ją do wymiaru płótna Canvas drukarki, więc problem skalowania masz juz rozwiązany, odpowiadają za to te elementy:

Kod: Zaznacz cały

  int PrnXRes 
= GetDeviceCaps(PrinterCanvas->Handle, LOGPIXELSX);
  int PrnYRes = GetDeviceCaps(PrinterCanvas->Handle, LOGPIXELSY);
  bmp_w = floor(((double)TheBitmap->Width / (double)Screen->PixelsPerInch) *
                                                         (double)PrnXRes);
  bmp_h = floor(((double)TheBitmap->Height / (double)Screen->PixelsPerInch) *
                                                           (double)PrnYRes);
  


Musisz dokładnie przejrzeć ten kod jeżeli chcesz coś w nim zmienić. Funkcje pewnie dałoby się uprościć i przyspieszyć, ale na to nie mam teraz czasu. Może trafi się ktoś kto to potrafi, póki co radź sobie z tym co masz.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie bitmapy

Nowy postprzez polymorphism » sobota, 12 czerwca 2010, 16:35

Funkcje pewnie dałoby się uprościć i przyspieszyć (...)

Przejrzałem sobie tę funkcję i nie mogę pojąć, po co autor tworzy a następnie kopiuje do h_mem_bmp zawartość TheBitmap, przecież wszystkie dane spokojnie wyciągnie z tej drugiej, źródłowej bitmapy. No i to mieszanie różnych funkcji alokujących pamięć, zupełnie pozbawione sensu - o new/delete zapomniał?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie bitmapy

Nowy postprzez Cyfrowy Baron » sobota, 12 czerwca 2010, 17:28

Może chodzi o to:

Kod: Zaznacz cały
::GetDIBits (h_dc, h_mem_bmp, 0, bmp_h, bits, bmp_info, DIB_RGB_COLORS);


Nie wiem. Nie analizowałem tego aż tak dokładnie. Poza tym wydaje mi się, że wystarczyłaby struktura BITMAPINFOHEADER i funkcja StretchDIBits. Cała ta zabawa z paletami jest chyba niepotrzebna.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Drukowanie bitmapy

Nowy postprzez polymorphism » sobota, 12 czerwca 2010, 18:02

Może chodzi o to: (...)

No dobra, ale zamiast h_mem_bmp mógł dać uchwyt TheBitmap i na to samo wyjdzie. Zresztą TBitmap przy odpowiednim ustawieniu PixelFormat staje się bitmapą typu DIB, a wtedy nawet wywołanie GetDIBits nie jest potrzebne (no chyba że chcemy w prosty sposób uzupełnić sobie BITMAPINFOHEADER), ponieważ dostęp do danych bitmapy mam poprzez ScanLine.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Poprzednia strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje multimedialne, graficzne

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości

cron