Programmēšana

Java padoms 60: bitkartes failu saglabāšana Java

Šis padoms papildina Java 43 padomu, kas parādīja bitkartes failu ielādes procesu Java lietojumprogrammās. Šajā mēnesī es sekoju apmācībai par to, kā saglabāt attēlus 24 bitu bitkartes failos, un koda fragmentu, kuru varat izmantot, lai rakstītu bitkartes failu no attēla objekta.

Spēja izveidot bitkartes failu paver daudzas durvis, ja strādājat Microsoft Windows vidē. Piemēram, manā pēdējā projektā man bija jāsaskaņo Java ar Microsoft Access. Java programma ļāva lietotājam uz ekrāna uzzīmēt karti. Pēc tam karte tika izdrukāta Microsoft Access pārskatā. Tā kā Java neatbalsta OLE, mans vienīgais risinājums bija izveidot kartes bitkartes failu un pateikt Microsoft Access ziņojumam, kur to paņemt. Ja jums kādreiz bija jāraksta lietojumprogramma, lai nosūtītu attēlu uz starpliktuvi, šis padoms jums var būt noderīgs - it īpaši, ja šī informācija tiek nodota citai Windows lietojumprogrammai.

Bitkartes faila formāts

Bitu kartes faila formāts atbalsta 4 bitu RLE (darbības garuma kodēšanu), kā arī 8 bitu un 24 bitu kodēšanu. Tā kā mēs nodarbojamies tikai ar 24 bitu formātu, apskatīsim faila struktūru.

Bitkartes fails ir sadalīts trīs sadaļās. Es tos jums izklāstīju zemāk.

1. sadaļa: Bitmap faila galvene

Šajā galvenē ir informācija par bitkartes faila veida lielumu un izkārtojumu. Struktūra ir šāda (ņemta no C valodas struktūras definīcijas):

typedef struct tagBITMAPFILEHEADER {UINT bfType; DWORD bfSize; UINT bfReserved1; UINT bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER; 

Tālāk ir aprakstīts iepriekš minētajā koda elementu apraksts:

  • bfType: Norāda faila tipu un vienmēr ir iestatīts uz BM.
  • bfSize: Norāda visa faila lielumu baitos.
  • bfRezervēts1: Rezervēts - jāiestata uz 0.
  • bfReserved2: Rezervēts - jāiestata uz 0.
  • bfOffBits: Norāda baita nobīdi no BitmapFileHeader līdz attēla sākumam.

Šeit jūs redzējāt, ka bitkartes galvenes mērķis ir identificēt bitkartes failu. Katra programma, kas lasa bitkartes failus, failu validācijai izmanto bitkartes galveni.

2. sadaļa: Bitmap informācijas galvene

Nākamais galvenes nosaukums informācijas galvene, satur visas paša attēla īpašības.

Lūk, kā jūs norādāt informāciju par Windows 3.0 (vai jaunākas) ierīces neatkarīgas bitkartes (DIB) izmēru un krāsu formātu:

typedef struct tagBITMAPINFOHEADER {DWORD biSize; LONG biWidth; GARS biAugstums; VĀRDS biPlanes; VĀRDS biBitCount; DWORD biKompresija; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrSvarīgi; } BITMAPINFOHEADER; 

Katrs iepriekš minētā kodu saraksta elements ir aprakstīts tālāk:

  • biSize: Norāda, cik baitu nepieciešams BITMAPINFOHEADER struktūru.
  • biWidth: Norāda bitkartes platumu pikseļos.
  • biHeight: Norāda bitkartes augstumu pikseļos.
  • biPlāni: Norāda mērķa ierīces plakņu skaitu. Šim dalībniekam jābūt iestatītam uz 1.
  • biBitCount: Norāda bitu skaitu pikseļos. Šai vērtībai ir jābūt 1, 4, 8 vai 24.
  • biokompresija: Norāda saspiestā bitkartes saspiešanas veidu. 24 bitu formātā mainīgais tiek iestatīts uz 0.
  • biSizeImage: norāda attēla lielumu baitos. Ir derīgi iestatīt šo dalībnieku uz 0, ja bitkarte ir BI_RGB formātā.
  • biXPelsPerMeter: norāda bitkartes mērķa ierīces horizontālo izšķirtspēju pikseļos uz metru. Lietojumprogramma var izmantot šo vērtību, lai izvēlētos bitu karti no resursu grupas, kas vislabāk atbilst pašreizējās ierīces īpašībām.
  • biYPelsPerMeter: norāda bitkartes mērķa ierīces vertikālo izšķirtspēju pikseļos uz metru.
  • biClrUsed: norāda krāsu indeksu skaitu krāsu tabulā, ko faktiski izmanto bitkarte. Ja biBitCount ir iestatīts uz 24, biClrLietots norāda atsauces krāsu tabulas lielumu, ko izmanto, lai optimizētu Windows krāsu paletes.
  • biClrImportant: norāda krāsu indeksu skaitu, kas tiek uzskatīts par svarīgu bitkartes parādīšanai. Ja šī vērtība ir 0, visas krāsas ir svarīgas.

Tagad ir definēta visa informācija, kas nepieciešama attēla izveidošanai.

3. sadaļa: attēls

24 bitu formātā katru attēla pikseļu attēlo RGB trīs baitu sērija, kas saglabāta kā BRG. Katra skenēšanas līnija ir polsterēta līdz pat 4 baitu robežai. Lai procesu vēl nedaudz sarežģītu, attēls tiek saglabāts no apakšas uz augšu, tas nozīmē, ka pirmā skenēšanas līnija ir attēla pēdējā skenēšanas līnija. Šajā attēlā redzamas abas galvenes (BITMAPHEADER) un (BITMAPINFOHEADER) un attēla daļa. Katru sadaļu norobežo vertikāla josla:

 0000000000 4D42 B536 0002 0000 0000 0036 0000 | 0028 0000000020 0000 0107 0000 00E0 0000 0001 0018 0000 0000000040 0000 B500 0002 0EC4 0000 0EC4 0000 0000 0000000060 0000 0000 0000 | FFFF FFFF FFFF FFFF FFFF 0000000100 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF * 

Tagad par kodu

Tagad, kad mēs visu zinām par 24 bitu bitkartes faila struktūru, lūk, ko jūs gaidījāt: kods, lai rakstītu bitkartes failu no attēla objekta.

importēt java.awt. *; importēt java.io. *; importēt java.awt.image. *; publiskā klase BMPFile paplašina komponentu {// --- privātās konstantes privātā galīgā statiskā int BITMAPFILEHEADER_SIZE = 14; privātā galīgā statiskā int BITMAPINFOHEADER_SIZE = 40; // --- privātā mainīgā deklarācija // --- bitkartes faila galvenes privātais baits bitmapFileHeader [] = jauns baits [14]; privāts baits bfType [] = {'B', 'M'}; privāts int bfSize = 0; privāts int bfReserved1 = 0; privāts int bfReserved2 = 0; private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE; // --- Bitmap informācijas galvenes privātais baits bitmapInfoHeader [] = jauns baits [40]; private int biSize = BITMAPINFOHEADER_SIZE; privāts int biWidth = 0; privāts int biHeight = 0; privātās int biPlanes = 1; privāts int biBitCount = 24; privātā int biKompresija = 0; privāts int biSizeImage = 0x030000; privāts int biXPelsPerMeter = 0x0; private int biYPelsPerMeter = 0x0; privāts int biClrUsed = 0; private int biClrSvarīgi = 0; // --- Bitmap raw data private int bitmap []; // --- failu sadaļa privāta FileOutputStream fo; // --- noklusējuma konstruktors public BMPFile () {} public void saveBitmap (String parFilename, Image parImage, int parWidth, int parHeight) {try {fo = new FileOutputStream (parFilename); saglabāt (parImage, parWidth, parHeight); fo.close (); } catch (izņēmums saveEx) {saveEx.printStackTrace (); }} / * * Saglabāšanas metode ir galvenā procesa metode. Šī metode * izsauks metodi convertImage, lai atmiņas attēlu pārveidotu par * baitu masīvu; metode writeBitmapFileHeader izveido un raksta * bitkartes faila galveni; writeBitmapInfoHeader izveido informācijas galveni *; un writeBitmap raksta attēlu. * * / private void save (Attēla parImage, int parWidth, int parHeight) {mēģiniet {convertImage (parImage, parWidth, parHeight); writeBitmapFileHeader (); writeBitmapInfoHeader (); writeBitmap (); } catch (izņēmums saveEx) {saveEx.printStackTrace (); }} / * * convertImage pārveido atmiņas attēlu bitkartes formātā (BRG). * Tas arī aprēķina informāciju par bitkartes informācijas galveni. * * / private boolean convertImage (Attēla parImage, int parWidth, int parHeight) {int spilventiņš; bitu karte = new int [parWidth * parHeight]; PixelGrabber pg = jauns PixelGrabber (parImage, 0, 0, parWidth, parHeight, bitmap, 0, parWidth); mēģiniet {pg.grabPixels (); } catch (InterruptedException e) {e.printStackTrace (); atgriešanās (nepatiesa); } pad = (4 - ((parWidth * 3)% 4)) * parHeight; biSizeImage = ((parWidth * parHeight) * 3) + spilventiņš; bfSize = biSizeImage + BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE; biWidth = parWidth; biHeight = parHeight; atgriešanās (taisnība); } / * * writeBitmap pārveido attēlu, kas atgriezts no pikseļu sagrābēja, * vajadzīgajā formātā. Atcerieties: skenēšanas līnijas ir apgrieztas * bitkartes failā! * * Katrai skenēšanas līnijai jābūt polsterētai līdz pat 4 baitu robežai. * / private void writeBitmap () {int izmērs; int vērtība; int j; int i; int rowCount; int rowIndex; int lastRowIndex; int spilventiņš; int padCount; baits rgb [] = jauns baits [3]; izmērs = (biWidth * biHeight) - 1; spilventiņš = 4 - ((biWidth * 3)% 4); if (pad == 4) // <==== Kļūdu labošanas bloks = 0; // <==== Kļūdu labošanas rindaSkaits = 1; padCount = 0; rowIndex = izmērs - biWidth; lastRowIndex = rowIndex; mēģiniet {for (j = 0; j> 8) & 0xFF); rgb [2] = (baits) ((vērtība >> 16) & 0xFF); fo.write (rgb); if (rowCount == biWidth) {padCount + = pad; (i = 1; i> 8) un 0x00FF); return (retValue); } / * * * intToDWord pārveido int dubultvārdā, kur atgriešanās * vērtība tiek saglabāta 4 baitu masīvā. * * / privāts baits [] intToDWord (int parValue) {baits retValue [] = jauns baits [4]; retValue [0] = (baits) (parValue & 0x00FF); retValue [1] = (baits) ((parValue >> 8) & 0x000000FF); retValue [2] = (baits) ((parValue >> 16) & 0x000000FF); retValue [3] = (baits) ((parValue >> 24) & 0x000000FF); return (retValue); }} 

Secinājums

Tas ir viss, kas tam ir. Esmu pārliecināts, ka šī klase jums šķitīs ļoti noderīga, jo, sākot ar JDK 1.1.6, Java neatbalsta attēlu saglabāšanu nevienā populārā formātā. JDK 1.2 piedāvās atbalstu JPEG attēlu izveidošanai, bet neatbalstīs bitkartes. Tātad šī klase joprojām aizpildīs robu JDK 1.2.

Ja spēlējaties kopā ar šo klasi un atrodat veidus, kā to uzlabot, dariet man zināmu! Mans e-pasts parādās kopā ar manu biogrāfiju.

Žans Pjērs Dubē ir neatkarīgs Java konsultants. Viņš dibināja Infocom, kas reģistrēts 1988. gadā. Kopš tā laika Infocom ir izstrādājis vairākas pielāgotas lietojumprogrammas, sākot no ražošanas, dokumentu pārvaldības un liela mēroga elektropārvades līniju pārvaldības. Viņam ir liela programmēšanas pieredze programmās C, Visual Basic un pavisam nesen Java, kas tagad ir galvenā valoda, kuru lieto viņa uzņēmums. Viens no jaunākajiem Infocom projektiem ir diagrammas API, kurai drīz vajadzētu kļūt pieejamai kā beta versijai.

Šo stāstu “Java Tip 60: Bitmap failu saglabāšana Java” sākotnēji publicēja JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found