Domanda

Mi piacerebbe essere in grado di creare una bitmap pixel di grandi dimensioni (diciamo 20.000 x 20.000) in un'applicazione MFC C ++, usando una classe derivata da CDC per scrivere sulla bitmap. Ho provato a utilizzare i controller di dominio di memoria come descritto nei documenti MSDN, ma questi sembrano essere limitati a dimensioni compatibili con l'attuale driver di visualizzazione.

Attualmente sto usando un driver di stampa bitmap per fare il lavoro, ma è estremamente lento e utilizza grandi quantità di memoria intermedia a causa dello spooling delle informazioni GDI.

La soluzione che sto cercando non dovrebbe comportare metafile o spooling, in quanto il modello che sto disegnando richiede molti milioni di chiamate GDI per il rendering.

Potrei usare un approccio di divisione e conquista tramite più DC di memoria, ma sembra una tecnica piuttosto ingombrante e inelegante.

qualche pensiero?

È stato utile?

Soluzione

CDC e CBitmap sembrano supportare solo bitmap dipendenti dal dispositivo, potresti avere più fortuna nel creare la tua bitmap con :: CreateDIBSection , quindi allegando una CBitmap a questo. Sfortunatamente, le interfacce GDI non elaborate sono un po 'ridicole.

Probabilmente non avrai molta fortuna con 20.000 x 20.000 a 32 BPP, almeno in un'applicazione a 32 bit, dato che esce a circa 1,5 GB di memoria, ma ho ottenuto un HBITMAP valido indietro con 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));

Altri suggerimenti

Questo è insolito poiché spesso ho creato un controller di dominio basato sullo schermo che verrà utilizzato per un'immagine bitmap che è molto più grande dello schermo - 3000 pixel più in alcuni casi - senza alcun problema. Hai qualche codice di esempio che mostra questo problema in azione?

Considerando una risoluzione dell'immagine così grande, non è possibile creare l'immagine utilizzando bitmap compatibili.

Esempio:

profondità pixel = 32 bit = 4 byte per pixel

numero di pixel = 20.000 * 20.000 = 400.000.000

byte totali = numero di pixel * 4 = 1.600.000.000 byte = 1.562.500 kb ~ = 1525 MB ~ = 1.5GB

Sto speculando sulle intenzioni finali, ma supponiamo che tu voglia creare e consentire agli utenti di esplorare un'immensa mappa con zoom molto dettagliati. È necessario creare un formato file immagine personalizzato; è possibile inserire all'interno di quel file vari livelli contenenti griglie di bitmap, ad esempio, per velocizzare il rendering. Il processo di rendering può utilizzare DIB GDI o GDI + per creare immagini parziali e renderle insieme. Naturalmente questo richiede un po 'di sperimentazione / ottimizzazione per raggiungere la perfetta sensazione dell'utente.

buona fortuna

Per mantenere l'utilizzo della memoria entro limiti accettabili, dovrai usare la tua strategia di "divisione e conquista". Non è un trucco, se implementato nel modo giusto è in realtà un modo molto elegante di gestire bitmap di dimensioni illimitate. Se lo si progetta nel modo giusto, è possibile combinare "solo rendering / mostra parte dell'immagine", "renderizzare l'intera immagine a bassa risoluzione per la visualizzazione su schermo" e "eseguire il rendering del tutto su una bitmap su disco" un motore e proteggi gli utenti del tuo codice (molto probabilmente tra due settimane;)) dagli interni. Lavoro su un prodotto con gli stessi problemi: rendering di mappe (potenzialmente di grandi dimensioni) sullo schermo o su file .bmp.

Se l'immagine deve avere questa risoluzione, ad esempio una scansione ad alta risoluzione di una radiografia, allora potresti voler guardare la scrittura di routine di spooling personalizzate per esso - 1,5 GB è molto costoso - anche per i desktop moderni.

Se è basato su vettori, puoi guardare SVG in quanto supporta le porte di visualizzazione e la maggior parte ti consente di eseguire il rendering in altri formati. Uso SVG per JPG tramite Batik (Java), quindi è possibile farlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top