Question

J'aimerais pouvoir créer une grande image bitmap de pixels (disons 20 000 x 20 000) dans une application C ++ MFC, en utilisant une classe dérivée de CDC pour écrire dans l'image bitmap. J'ai essayé d'utiliser des contrôleurs de domaine mémoire, comme décrit dans la documentation MSDN, mais ces derniers semblent être limités aux tailles compatibles avec le pilote d'affichage actuel.

J'utilise actuellement un pilote d'imprimante bitmap pour effectuer le travail, mais il est extrêmement lent et utilise de très grandes quantités de stockage intermédiaire en raison de la mise en file d'attente des informations GDI.

La solution que je recherche ne devrait pas impliquer de métafichiers ni de spooling, car le modèle que je dessine prend plusieurs millions d’appels GDI à restituer.

Je pourrais utiliser une approche diviser pour régner via plusieurs contrôleurs de domaine mémoire, mais cela semble être une technique assez fastidieuse et inélégante.

des pensées?

Était-ce utile?

La solution

CDC et CBitmap semblent ne prendre en charge que les bitmaps dépendantes du périphérique. Vous aurez peut-être plus de chance en créant votre bitmap avec :: CreateDIBSection , puis y attacher un CBitmap. Les interfaces GDI brutes sont malheureusement un peu effrayantes.

Vous n'aurez probablement pas beaucoup de chance avec 20 000 x 20 000 à 32 BPP, du moins dans une application 32 bits, car cela ne nécessite qu'environ 1,5 Go de mémoire, mais j'ai reçu un HBITMAP valide avec 16 bpp:

BITMAPINFOHEADER bmi = { sizeof(bmi) };
bmi.biWidth = 20000;
bmi.biHeight = 20000;
bmi.biPlanes = 1;
bmi.biBitCount = 16;
HDC hdc = CreateCompatibleDC(NULL);
BYTE* pbData = 0;
HBITMAP hbm = CreateDIBSection(hdc, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (void**)&pbData, NULL, 0);
DeleteObject(SelectObject(hdc, hbm));

Autres conseils

Ceci est inhabituel car j’ai souvent créé un contrôleur de domaine basé sur l’écran qui sera utilisé pour une image bitmap beaucoup plus grande que l’écran - 3 000 pixels voire plus dans certains cas - sans aucun problème. Avez-vous un exemple de code montrant ce problème en action?

En raison d'une résolution d'image aussi grande, vous ne pouvez pas créer d'image à l'aide de bitmaps compatibles.

Exemple:

profondeur de pixel = 32 bits = 4 octets par pixel

nombre de pixels = 20 000 * 20 000 = 400 000 000

nombre total d'octets = nombre de pixels * 4 = 1.600.000.000 octets = 1.562.500 kb ~ = 1525 Mo ~ = 1,5 Go

Je spécule sur les intentions finales, mais supposons que vous souhaitiez créer et permettre aux utilisateurs d'explorer une immense carte avec des zooms très détaillés. Vous devez créer un format de fichier image personnalisé. vous pouvez insérer dans ce fichier différentes couches contenant des grilles de bitmaps, par exemple, pour accélérer le rendu. Le processus de rendu peut utiliser des fichiers DIB GDI ou GDI + pour créer des images partielles, puis les restituer ensemble. Bien sûr, il faut expérimenter / optimiser pour atteindre le sentiment d'utilisateur idéal.

bonne chance

Pour que votre utilisation de la mémoire reste dans des limites acceptables, vous devez utiliser votre stratégie de division et de conquête. Ce n'est pas un hack, s'il est correctement mis en œuvre, c'est en fait un moyen très élégant de traiter des bitmaps de taille illimitée. Si vous le concevez correctement, vous pouvez combiner les approches "uniquement le rendu / l'affichage de l'image", "le rendu de l'image entière à basse résolution pour l'affichage à l'écran" et le rendu du tout dans une image bitmap sur disque " un moteur et protégez les utilisateurs de votre code (probablement dans deux semaines;)) des internes. Je travaille sur un produit présentant les mêmes problèmes: le rendu (potentiellement volumineux) de cartes, soit à l'écran, soit vers des fichiers .bmp.

Si l'image doit avoir cette résolution - par exemple, une analyse haute résolution d'une radiographie -, vous voudrez peut-être écrire des routines de mise en file d'attente personnalisées - 1,5 Go est très coûteux, même pour les ordinateurs de bureau modernes.

S'il s'agit d'un vecteur, vous pouvez regarder SVG car il prend en charge les ports d'affichage et vous permet généralement de rendre le rendu dans d'autres formats. J'utilise SVG en JPG via Batik (java), il est donc possible de le faire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top