|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
你精通任何一门语言就最强大。现在来看,java的市场比C#大,C#容易入手,比较简单,java比较难
From:http://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html
Thisfirstsectionofthisarticlegivesanintroductiontocolorsandshowshowanimagerecordsthecolorvalueofeachpixel.
IntroductionImagelifecycleImageDataColorPaletteDataIndexedpaletteDirectpaletteThenextsectiondescribesimagetransparency,alphablending,animation,andhowtoscaleimages.TransparencyManipulatingImageDataSavingImagesBlendingSinglealphavalueDifferentalphavalueperpixelImageeffectsGIFanimationScalingFinally,thearticleshowshowtocreatecursorsfromimages,byusingasourceimagetogetherwithamask.CursorsPlatformcursorsCustomcursorsIntroductionThesimplestwaytocreateanSWTImageistoloaditfromarecognizedgraphicfileformat.ThisincludesGIF,BMP(Windowsformatbitmap),JPG,andPNG.TheTIFFformatisalsosupportedinmorerecentEclipsereleases.ImagescanbeloadedfromaknownlocationinthefilesystemusingtheconstructorImage(Displaydisplay,StringfileLocation):
Imageimage=newImage(display,"C:/eclipse/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif");
Insteadofhard-codingthelocationoftheimage,itsmorecommontoloadtheImagefromafolderlocationrelativetoagivenclass.ThisisdonebycreatinganInputStreampointingtothefilewiththemethodClass.getResourceAsStream(Stringname),andusingtheresultastheargumenttotheconstructorImage(Displaydisplay,InputStreaminputStream).
TheEclipsepackageexplorerbelowshowstheclasscom.foo.ShellWithButtonShowingEclipseLogoandtheeclipse_lg.gifinthesamefolder.Tofollowingcodewouldloadthegraphicfromitslocationrelativetotheclass.
Imageimage=newImage(display,ShellWithButtonShowingEclipseLogo.class.getResourceAsStream("eclipse_lg.gif"));
OncetheimagehasbeencreateditcanbeusedaspartofacontrolsuchasaButtonorLabelthatisabletorenderthegraphicaspartoftheirsetImage(Imageimage)methods.
Buttonbutton=newButton(shell,SWT.PUSH);button.setImage(image);
ImagescanbedrawnontousingagraphicscontextthatiscreatedwiththeconstructorGC(Drawabledrawable)withtheImageastheargument.
GCgc=newGC(image);gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));gc.drawText("Ivebeendrawnon",0,0,true);gc.dispose();
UsingaGCtodrawontoanImagepermanentlyaltersthegraphic.MoreinformationonhowtouseaGCiscoveredinthearticleGraphicsContext-Quickonthedraw.
ImagelifecycleWhenanimageisloaded,thefirststepistocreatedeviceindependentImageDatarepresentedbytheclassorg.eclipse.swt.graphics.ImageData.Followingthis,thedataispreparedforaspecificdevicebycreatinganactualImageinstance.
AswellasloadinganImagedirectlyfromafile,youcanseparatelycreatetheImageDataobjectandthenconstructtheImageusingImage(Devicedevice,ImageDataimageData).ThedataforanexistingImagecanberetrievedusinggetImageData(),althoughthiswillnotbethesameobjectthatwasusedtocreatetheimage.Thisisbecausewhenpreparinganimagetobedrawnontoascreen,propertiessuchasitscolordepthmightbedifferentfromtheinitialimagedata.
InstancesofImagerepresentanunderlyingresourcethathasbeenpreparedforaspecificdeviceandtheymustbedisposedwhentheyarenolongerrequiredtofreeuptheallocatedresource.ThereisnofinalizationofresourcesinSWTwhenanobjectisgarbagecollected.FormoreinformationseeSWT:TheStandardWidgetToolkit:ManagingOperatingSystemResources.
ImageDataImageDatacanbethoughtofasthemodelforanimage,whereastheImageistheviewthatsbeenpreparedforoutputontoaspecificdevice.TheImageDatahasawidthandheight,andapixelvalueforeachcoordinate.Therawdataoftheimageisabyte[],andthedepthoftheimagespecifiesthenumberofbitsthatareusedforeachcoordinate.Animagedepthof1canstoretwopossiblevaluesforeachpixel(0and1),adepthof4canstore2^4=16,adepthof8canstore2^8=256valuesandadepthof24canrepresent2^24=16milliondifferentvaluesperpixel.Thelargerthedepthofanimagethemorebytesarerequiredforitspixels,andsomeformatssuchasGIFthatwereinitiallydesignedfordownloadacrossinternetconnectionsonlysupportamaximumdepthof8.Howthevalueofeachpixelvaluetranslatesintoanactualcolordependsonitspaletterepresentedbytheclassorg.eclipse.swt.graphics.PaletteData.
ThenextsectiondescribeshowcolorsarerepresentedbytheirRGBvalues,andhowPaletteDatamapsamappixelvaluetoaparticularcolor.
ColorTheclassorg.eclipse.swt.graphics.ColorisusedtomanageresourcesthatimplementtheRGBcolormodel.Eachcolorisdescribedintermsofitsred,greenandbluecomponent(eachexpressedasanintegervaluefrom0fornocolorto255forfullcolor).
ColorcyanColor=newColor(display,0,255,255);//...CodetousetheColorcyanColor.dispose();
Theconvenienceclassorg.eclipse.swt.graphics.RGBexistsinSWTthatcombinesacolorsred,greenandbluevaluesintoasingleobject.
RGBcyanRGB=newRGB(0,255,255);ColorcyanColor=newColor(display,cyanRGB);//...CodetousetheColorcyanColor.dispose();
TheColorinstanceshouldbedisposedwhenitisnolongerrequired,whereastheRGBhasnoneedtobedisposed.ThisissimilartotherelationshipbetweenanImageanditsImageData,whereColorandImagearedevicespecificobjectsusingunderlyingnativeresources,whileRGBandImageDataaretheunderlyingmodeldata.
Toavoidhavingtocreateandmanageinstancesofthecommonlyusedcolors,theDisplayclassallowthesetoberetrievedusingthemethodDisplay.getSystemColor(intid).
ColorcyanColor=display.getSystemColor(SWT.COLOR_CYAN)
WhenaColorisobtainedbyanSWTprogramusingthemethodDisplay.getSystemColor(intid)method,itmustnotbedisposed.TheruleofthumbthatworksforanySWTresourceis"Ifyoucreatedit,youareresponsiblefordisposingit".Becausethestatementaboveretrievedthecyancolorinstance,anddidntexplicitlyconstructit,itshouldnotbedisposed.
HowaColorisactuallyrepresentedonthedisplaydependsonfactorssuchastheresolutionanddepthofthedisplay.FormoreinformationonthisandtheSWTcolormodelseeSWTColorModel.
PaletteDataTherearetwokindsofPaletteData,anindexedpaletteandadirectpalette.PaletteDataisamodelofhowpixelvaluesmaptoRGBvalues,andbecausetheydonotrepresentanunderlyingresource,theydonotrequiredisposing.IndexedpaletteWithanindexedpaletteeachpixelvaluerepresentsanumberthatisthencrossindexedwiththepalettetodeterminetheactualcolor.Therangeofallowablepixelvaluesisthedepthoftheimage.
Theexamplebelowisa48by48squareimagecreatedwithadepthof1,andanindexedcolorpalette.Theindexedpaletteassigns0toberedand1tobegreen(byvirtueoftheirorderintheRGB[]intheconstructor).TheImageDatasun-initializedpixelvalueswillinitiallybe0(red),andtwoforloopsseta34by34squareinthecenteroftheImageDatatobe1(green).
PaletteDatapaletteData=newPaletteData(newRGB[]{newRGB(255,0,0),newRGB(0,255,0)});ImageDataimageData=newImageData(48,48,1,paletteData);for(intx=11;x<35;x++){for(inty=11;y<35;y++){imageData.setPixel(x,y,1);}}Imageimage=newImage(display,imageData);
Theaboveexamplehasadepthof1soitcanstore2colors,butasthecolordepthoftheImageDataincreasesthensocanthenumberofcolorsinthepalette.Anindexedpalettecanhavea1,2,4,or8bitdepths,andan8bitdepthprovides2^8=256possiblecolors.Tohaveahighercolordepth(suchas16,24,or32)adirectpalettemustbeused.
DirectpaletteInsteadofhavingeachpixelvaluerepresentanindexinthepalettecorrespondingtoitscolor,adirectpaletteallowseachpixelvaluetodirectlyrecorditsred,greenandbluecomponent.AdirectPaletteDatadefinesred,greenandbluemasks.Thesemasksarenumberofbitsrequiredtoshiftapixelvaluetotheleftsothehighbitofthemaskalignswiththehighbitofthefirstbyteofcolor.Forexample,a24bitdirectpalettecandivideitselfinto3portions,storingredinthelowest8bits,greeninthecentral8bitsandblueinthehighest8bits.Theredshiftmaskwouldbe0xFF,green0xFF00andblue0xFF0000.
Thevalueforeachpixelrepresentsacombinationofthered,greenandbluecomponentsintoasingle24bitinteger.Toconstructanindexedpalettetheconstructorusedallowsthered,greenandbluecolormaskstobespecified.
PaletteDatapalette=newPaletteData(0xFF,0xFF00,0xFF0000);ImageDataimageData=newImageData(48,48,24,palette);
Usingthesametechniqueasearlier,thecodeiteratesovereverypixelcoordinatesettingittoeither0xFF(forred)or0xFF00(forgreen).
for(intx=0;x<48;x++){for(inty=0;y<48;y++){if(y>11&&y<35&&x>11&&x<35){imageData.setPixel(x,y,0xFF00);//Setthecentertogreen}else{imageData.setPixel(x,y,0xFF);//andeverythingelsetored}}};Imageimage=newImage(display,imageData);
Thiscreatestheresultbelowwheretheimageisredwithagreencenter.
Becauseyoucanusecolordepthsof16,24and32bitswithdirectpalettes,youcanrepresentmorecolorsthanareavailablewithanindexedpalettewhosemaximumdepthis8.Acolordepthof24allowsyoutorepresent16millioncolors(2^24).Thetradeoffhoweverissize,becauseanindexedpalettewithadepthof8requiresonebyteperimagecoordinatewhereasadirectpalettewithadepthof24requiresthreebytesperimagecoordinate.
WithbothdirectandindexedpalettesyoucangofromanRGBtoapixelvalueandvice-versausingthepublicmethodsintgetPixel(RGBrgb)andRGBgetRGB(intpixelValue).
TransparencyThepurposeoftransparencyistomakeaportionoftheimagenon-opaque,sowhenitisdrawnonaGUIsurfacetheoriginalbackgroundshowsthrough.Thisisdonebyspecifyingthatoneoftheimagecolorsistransparent.Wheneverapixelwiththetransparentcolorvalueisdrawn,insteadofusingtheRGBvaluedefinedinthepalettetheoriginaldestinationbackgroundpixelcolorisusedinstead.Theeffecttotheuseristhattheareasoftheimagethatequalthetransparentpixelshowthebackgroundofwhatevertheimageisbeingdrawnover,thusachievingtransparency.PersistedimagefileformatssuchasGIForBMPallowyoutospecifyatransparentpixelvalue,althoughonlyifthepaletteisindexedandthecolordepthis8orless.
WhenImagesareuseddirectlyoncontrolssuchasButtonorLabelthenativebehaviormaybethattransparentpixelsareignoredanddrawninthepixelcolorspecifiedbythesource.NativeimagetransparencyhoweverissupportedinSWTforoperationsinvolvingaGC.ToillustratethisthefollowingfileIdea.gifhasacolordepthof8,andthewhitepixel(index255inthepalette)settobethetransparentpixel.
TheshellbelowhasaLabelontheleftwithaCanvasnexttoit.TheIdea.gifisusedasthelabelsimage,andalsointhepainteventoftheCanvas.BecausetheLabeldoesnotsupportnativetransparencytheoriginalwhitecolorofthetransparentpixelisusedasthebackground,howevertheGCinthepainteventrespectsthetransparentpixelandthegreybackgroundshowsthrough.
ImageideaImage=newImageData(getClass().getResourceAsStream("Idea.gif"));Labellabel=newLabel(shell,SWT.NONE);label.setImage(ideaImage);Canvascanvas=newCanvas(shell,SWT.NO_REDRAW_RESIZE);canvas.addPaintListener(newPaintListener(){publicvoidpaintControl(PaintEvente){e.gc.drawImage(ideaImage,0,0);}});
FortheaboveexampleIstackedthedeckinmyfavor,becauseIdidntactuallyusetheideagraphicthatisincludedwitheclipsearticlesintheirbanner.ThereasonisthattheoriginalgraphicisaJPGfilewhichdoesntsupporttransparency,soIusedagraphicstooltoconvertittoaGIFandsetthevalueofthewhitepixelinthepalettetobethetransparencypixel.TheoriginalIdea.jpgisshownbelow,andalthoughitlooksthesameastheIdea.gif,thisisbecauseitisonthewhitebackgroundoftheHTMLbrowser.
ByusingtheoriginalJPGfilethisoffersagoodexampleofhowwetoachieveatransparencyeffectprogrmaticallybymanpulatingitsImageData.TheImageDataclasshasapublicfieldtransparentPixeltospecifywhichpixelistransparentthatcanbesetonceapersistedimagefileisloadedintoanImageDatainstance,irrespectiveofwhetherthepersistedfileformatsupportstransparency.
ThecodebelowloadstheIdea.jpgfileinanImageDataobjectandsetsthetransparentpixelfortheImageDatatobethepixelvalueofthecolorwhiteinthepalette.ThepixelvalueintheindexedpalettethatrepresentswhiteisretrievedbyusinggetPixel(RGB).ThemanipulatedImageDataisusedtocreateanImagetransparentIdeaImagethatnowhasthewhitepixelvaluespecifiedtobetransparent.
ImageDataideaData=newImageData(getClass().getResourceAsStream("Idea.jpg"));intwhitePixel=ideaData.palette.getPixel(newRGB(255,255,255));ideaData.transparentPixel=whitePixel;ImagetransparentIdeaImage=newImage(display,ideaData);
NextaShellusesthenewlycreatedimageinanativeLabelandalsointhepainteventofaCanvas.AWindowsLabeldoesnotsupportnativetransparencysoitstillappearswithawhitebackground,howevertheGCfortheCanvasusestheexistingbackgroundcolorwheneverawhitepixelisencounteredinthesourceimage,sotheimageappearsastransparent.
LabeltransparentIdeaLabel=newLabel(shell,SWT.NONE);transparentIdeaLabel.setImage(transparentIdeaImage);Canvascanvas=newCanvas(shell,SWT.NONE);canvas.addPaintListener(newPaintListener(){publicvoidpaintControl(PaintEvente){e.gc.drawImage(transparentIdeaImage,0,0);}});
Ascanbeseenfromthesecondofthetwoimages(drawnontheCanvaswiththewhitepixelsettotransparent),therearestillsomepatchesofwhite.Closeranalysisrevealsthatthisisnotabug,butthattheseregionsarenotpurewhite(255,255,255),butareslighlyoff-white(suchas255,254,254).ThetransparentpixelofanImageDatacanonlybeusedforasinglevalue.Thisnowpresentsthenextproblemtobesolved-locatealloftheoff-whitepixelsintheImageDataandconvertthemtopure-white.Todothiswewilliterateovereachpixelintheimagedataandmodifythosethatareclosetowhitetobepurewhite.
ManipulatingImageDataBecausethegraphicIdea.jpgisntaswhiteaswedlikeit,welliterateoveritsimageDataandconverttheoff-whitepixelstopurewhiteandthenwellsavethisintoanewfileIdea_white.jpg.InpracticeitsunlikelythatyoudeverdothiskindofprogramminginSWT,howeveritsagoodexampletouseshowinghowImageDatacanbeanalyzedandmanipulated.
Thefirststepistoloadtheimageandtheniterateovereachpixelindividuallylookingatitscolor.BecauseIdea.jpgisusingadirectpalette,thepixelvalueisanintthatcontainsthered,greenandbluecomponentasmaskedbitareas.Thesemaskvaluecanbeobtainedfromthepalette.
ImageDataideaImageData=newImageData(getClass().getResourceAsStream("Idea.jpg"));intredMask=ideaImageData.palette.redMask;intblueMask=ideaImageData.palette.blueMask;intgreenMask=ideaImageData.palette.greenMask;
ForanypixelvaluewecanbitwiseANDitwiththemasktoseewhatthecolorcomponentis.Theredcomponentistheloworderbitssothiswillbetheactualvalue(from0to255),howeverthegreenandbluevaluesneedadjustingastheyarethehighorderbitsinthepixelvalue.Tomakethisadjustmentthecolorcomponentcanbebitshiftedtotherightusingthe>>operator.Ifyouarewritinggenericcodetodothiskindofmanipulating,takecarethatdirectpalettesforcolordepthsof24or32storetheircolorcomponentswithredbeingtheloworderbits,howeverforcolordepthof16thecolorsarereversedandredishighorderwithbluebeingloworder.ThereasonforthisistobethesameashowWindowsstoresimagesinternallysothereislessconversionwhencreatingtheimage.
TwoforloopswilliterateovertheimageData.Thefirstistraversingtheimagefromtoptobottomalineatatime,andcreatesanint[]toholdeachlineofdata.ThemethodImageData.getPixels(intx,inty,intgetWidth,int[]pixels,intstartIndex)isusedtoextractalineatatimefromtheimageDatasbytes.TheAPIforthismethodisslightlyirregular,becauseratherthanreturningtheresultingdataitinsteadisdeclaredasvoid,andtheresultingpixeldataisinjectedintotheint[]thatispassedinasamethodargument.Theint[]ofpixelsistheniteratedoverandeachvaluehasitsred,greenandbluecomponentextracted.Thedesiredeffectwewantistodeterminewhetherthepixelisoff-whiteandifsotomakeitpurewhite-arulethatworkswellistoassumethatanythingwhoseredandgreencomponentarehigherthan230andbluecomponenthigherthan150isanoff-white.
int[]lineData=newint[ideaImageData.width];for(inty=0;y<ideaImageData.height;y++){ideaImageData.getPixels(0,y,width,lineData,0);//Analyzeeachpixelvalueinthelinefor(intx=0;x<lineData.length;x++){//Extractthered,greenandbluecomponentintpixelValue=lineData[x];intr=pixelValue&redShift;intg=(pixelValue&greenShift)>>8;intb=(pixelValue&blueShift)>>16;if(r>230&&g>230&&b>150){ideaImageData.setPixel(x,y,0xFFFFFF);}}};
HavingmanipulatedtherawbytesmakinguptheImageDatawehavenowsuccessfullychangedtheoff-whitevaluestopurewhite.
SavingImagesNowthatwehavetheImageDatawhereallofthewhitishpixelshavebeenconvertedtowhite,andthetransparencypixelofthepalettehasbeensettobethecolorwhite,wellsavethisimagesothatnexttimeanSWTprogramneedsthepurewhiteJPFitcanjustloadthefileanduseitasis.TosaveImageDataintoafileusetheclassorg.eclipse.swt.graphics.ImageLoader.TheimageloaderhasapublicfielddatatypedtoImageData[].ThereasonthedatafieldisanarrayofImageDataistosupportimagefileformatswithmorethanoneframesuchasanimatedGIFsorinterlacedJPEGfiles.ThesearecoveredmoreintheAnimationsectionlater.
ImageLoaderimageLoader=newImageLoader();imageLoader.data=newImageData[]{ideaImageData};imageLoader.save("C:/temp/Idea_PureWhite.jpg",SWT.IMAGE_JPEG);
Thefinishedresultisshownbelow.
ItdoesntlookmuchdifferenttotheoriginalIdea.jpgbecauseitisdrawnonawhitebackground,butwhenitisdrawnonaCanvaswiththewhitepixelsettobethetransparentpixelthebackgroundshowsthroughachievingthedesiredeffect.
ImageDatapureWhiteIdeaImageData=newImageData("C:/temp/Idea_PureWhite.jpg");pureWhiteIdeaImageData.transparentPixel=pureWhiteIdeaImageData.palette.getPixel(newRGB(255,255,255));finalImagetransparentIdeaImage=newImage(display,pureWhiteIdeaImageData);Canvascanvas=newCanvas(shell,SWT.NONE);canvas.addPaintListener(newPaintListener(){publicvoidpaintControl(PaintEvente){e.gc.drawImage(transparentIdeaImage,0,0);}});
ItmightseemoddthatintheabovecodethatafterloadingtheIdea_PureWhite.jpgfilethetransparentpixelwassettobewhite.WhynotsetthetransparentpixelbeforeweusedtheImageLoadertocreatethepersistedIdea_PureWhite.jpgfile?ThereasonisthattheJPEGimagefileformatdoesnotsupporttransparency.AGIFfilesupportsnativetransparency,howeverchangingthefiletypetoSWT.IMAGE_GIFontheImageLoaderwouldnothaveworked,becauseGIFsupportsamaximumimagedepthof8andusesanindexedpalette,whereastheJPEGhasanimagedepthof24andadirectpalette.ToconvertbetweenthetwoformatswouldrequireanalyzingthecoloursusedbytheJPEGtocreatethebestfit256colorpalette,beforeiteratingovereachJPEGpixelvalueandcreatingtheGIFimagedatabyfindingtheclosestcolor.Doingthisconversionisoutsidethescopeofthisarticle,althoughitcanbedonebymostcommercialgraphicstools.Tomatchpixelvaluesasthecolordepthdecreasesfrom24to8involvesalgorithmsthatfindtherightcolormatchforablockofpixelsratherthanasinglepixelvalue,andiswhyimagequalitycansometimesbereducedwhenswitchingbetweendifferentformats.
WehaveshownhowanImageDataisanarrayofintvaluesrepresentingeachpixelcoordinate,andhoweachpixelvalueismappedtoacolorthroughthepalette.ThisallowedustoiterateovertheimagedatafortheIdea.jpg,querypixelvaluesthatwereclosetowhite,andconvertthesetoapurewhiteRGBvalue.TheendresultofthiswasthatwewereabletocreatetheIdea_PureWhite.jpgfilethatcanbeusedasatransparentJPGbysettingthewhitepixeltobetransparent.Transparencyworksbyhavingasourcepixelvalue(theimagebeingdrawn),adestinationpixelvalue(theimagebeingdrawnonto)andarulebywhichtheresultingdestinationpixelvalueisdetermined.Fortransparencytheruleisthatthesourcepixelvalueisusedunlessitstransparentinwhichcasethedestinationpixelisused.Anothertechniqueistousealphavaluesthatspecifytheweightappliedtothesourcerelativetothedestinationtocreatethefinalpixelvalue.Thisallowstheblendingbetweenthesourceimageandtheexistingbackgrounditisbeingdrawnonto.
BlendingAlphablendingisatechniqueusedtomergetwopixelvalues,wherethesourceanddestinationpixeleachspecifyanalphavaluethatweightshowmuchtheywillaffectthefinaldestinationpixel.Analphavalueof255isfullweight,and0isnoweight.SWTsupportsasinglealphavaluefortheentireImageData,orelseeachpixelcanhaveitsownalphavalue.SinglealphavalueTheintfieldalphaValueofImageDataisusedtospecifyasinglevaluethatweightshowthesourcepixelsarecombinedwiththedestinationinputtocreatethedestinationoutput.ThelistingbelowshowshowthesameImageDatafortheIdea_PureWhite.jpgisusedforthreeseparateimages.Thefirstistheoriginal,thenanalphaof128isused,andfinallyanalphaof64.NotethatthesameImageDataiscontinuallymanipulatedbyhavingitsalphachangedbeforecreatingeachImage,andchangingtheImageDatahasnoaffectonImagesalreadyconstructedusingit.ThisisbecausetheImageispreparedfordisplayonthedevicefromtheImageDataatconstructiontime.
Shellshell=newShell(display);shell.setLayout(newFillLayout());ImageDataimageData=newImageData("C:/temp/Idea_PureWhite.jpg");finalImagefullImage=newImage(display,imageData);imageData.alpha=128;finalImagehalfImage=newImage(display,imageData);imageData.alpha=64;finalImagequarterImage=newImage(display,imageData);
Canvascanvas=newCanvas(shell,SWT.NO_REDRAW_RESIZE);canvas.addPaintListener(newPaintListener(){publicvoidpaintControl(PaintEvente){e.gc.drawImage(fullImage,0,0);e.gc.drawImage(halfImage,140,0);e.gc.drawImage(quarterImage,280,0);}});
DifferentalphavalueperpixelAswellashavingasinglealphavaluethatappliedtoallpixelsinthesourceimage,ImageDataallowseachpixeltohaveitsownindividualalphavalue.Thisisdonewiththebyte[]fieldalphaData.Thisallowseffectstobeachieved,suchashavinganimagefadefromitstoptobottom.
ThefollowingcodecreatesanalphaDatabyte[],andthenhastwoloops.Theouterloopyisfrom0totheimageDatasheight,andtheinnerloopcreatesabyte[]forthewidthoftheimageDataandinitializesitwithavaluethatincreasesfrom0forthetoprowthroughto255forthebottomrow.ASystem.arrayCopythenbuildsupthealphaDatabyte[]witheachrow.
ImageDatafullImageData=newImageData("C:/temp/Idea_PureWhite.jpg");intwidth=fullImageData.width;intheight=fullImageData.height;byte[]alphaData=newbyte[height*width];for(inty=0;y<height;y++){byte[]alphaRow=newbyte[width];for(intx=0;x<width;x++){alphaRow[x]=(byte)((255*y)/height);}System.arraycopy(alphaRow,0,alphaData,y*width,width);}fullImageData.alphaData=alphaData;ImagefullImage=newImage(display,fullImageData);
Theresultingimageisshownbelow,andthealphaDatabyte[]makesthetopoftheimagetransparentandthebottomopaque,withagradualfadingbetweenthetwo.
ImageeffectsAswellasarbitraryimageeffectsthatcanbeachievedbymanipulatingimagedata,SWTprovidesanumberofpre-definedwaysofcreatingnewimagesbasedonexistingimagescombinedwithcertainstyles.Thisisusedif,forexample,youhaveanimagebeingusedonatoolbarbuttonandyouwishtocreateaversionthatcanbeusedtoindicatethatthebuttonisdisabledorthatitisinactive.
TocreateaneffectbasedonanexistingimageandastyleflagusetheconstructorImage(Displaydisplay,Imageimage,intflag).TheflagargumentisastaticconstantofeitherSWT.IMAGE_COPY,SWT.IMAGE_DISABLEorSWT.IMAGE_GRAY.CopycreatesanewimagebasedontheoriginalbutwithacopyofitsimageData,whereasDisableandGraycreateanewimageapplyingplatformspecificeffects.ThefollowingcodeshowstheIdea.jpg,togetherwiththreemoreimagesthatwecreatedusingthestylebitsIMAGE_DISABLE,IMAGE_GRAYandIMAGE_COPY.ToshowthatIMAGE_COPYcreatesanewimageaGCisusedtodrawontoitthataffectsonlythecopiedimage,nottheoriginal.
ImageideaImage=newImage(display,getClass().getResourceAsStream("/icons/Idea.jpg");ImagedisabledImage=newImage(display,image,SWT.IMAGE_DISABLE);ImagegrayImage=newImage(display,image,SWT.IMAGE_GRAY);ImagecopyImage=newImage(display,ideaImage,SWT.IMAGE_COPY);GCgc=newGC(copyImage);gc.drawText("Thisisacopy",0,0);gc.dispose();
GIFAnimationAnotherimportanttopicforimagesisunderstandinganimationwhereanimagecancontainanumberofframesthatareanimatedinsequence.ImageanimationissupportedbyGIFimages,whereasingleimagefilecancontainmultiplesetsofImageData.Webbrowserssupportnativeanimation,andthefollowingimageismadeupof15framesshowingthepenrotatingandwritingthewordsSWTbeneaththeIdealogo.
WhilethewebbrowseryoureusingtoreadthisarticleshouldshowtheIdea_SWT_Animation.giffileasasequencewiththemovingpen,thisisnottrueofnativeSWTcontrolsdisplayingthegraphic.Theanimationmustbedoneprogrammatically,andtheclassorg.eclipse.swt.examples.ImageAnalyzershowshowthiscanbeachieved.TheImageAnalyzerclasscanbeobtainedfromtheSWTexamplesprojectintheEclipseCVSrepository.
WhenananimatedGIFisloadedbytheImageLoaderclass,eachindividualframeisaseparateelementinthedatafieldarraytypedtoImageData[].IntheanimationsequenceeachImageDatarecordshowmanymillisecondsitshouldbedisplayedforintheintfielddelayTime.Thenumberoftimesthesequenceshouldrepeatcanberetrievedfromthefieldloader.repeatCount,avalueof-1indicatesthattheanimationshouldrepeatindefinitelyandIdea_SWT_Animation.gifhasthisvalue.Whenswitchingfromoneframetothenexttherearethreewaysthatthenewframecanreplacethepreviousone,specifiedbytheintfieldImageData.disposalMethod.Thiscantakethefollowingvaluesdefinedintheconstantclassorg.eclipse.swt.SWT.DM_FILL_NONELeavethepreviousimageinplaceandjustdrawtheimageontop.Eachframeaddstothepreviousone.DM_FILL_BACKGROUNDFillwiththebackgroundcolorbeforepaintingeachframe.Thepixelvalueforthisisdefinedinthefieldloader.backgroundPixelDM_FILL_PREVIOUSRestorethepreviouspictureDM_FILL_UNSPECIFIEDNodisposalmethodhasbeendefined
Toconserveonspace,animatedGIFsaregenerallyoptimizedtojuststorethedeltathatneedstobeappliedtothepreviousimage.IntheIdea_SWT_Animation.gifabovethe15framesareshownbelow.Eachframestoresadeltaagainstthepreviousimage,andthiswasautomaticallygeneratedbythetoolIcreatetheanimatedGIFwith.ThedisposalmethodforeachframeisDM_NONEsotheeachimageshouldbedrawnontopofthepreviousone.EachindividualImageDataelementhasthexandyforitstopleftcorner,aswellasitswidthandheight.Theoverallsizetousecanbeobtainedfromthefieldsloader.logicalScreenWidthandloader.logicalScreenHeight.
ToillustratehowtodisplayananimatedGIFinSWTwellcreateaninitialImagefromthefirstframeandacountertostorewhichframeisbeingdisplayed.TheimageisdrawnapainteventonaCanvas,andaGCiscreatedthatwillbeusedtodrawthesubsequentframesontotheimage.
ImageLoaderloader=newImageLoader();loader.load(getClass().getResourceAsStream("Idea_SWT_Animation.gif"));Canvascanvas=newCanvas(shell,SWT.NONE);image=newImage(display,loader.data[0]);intimageNumber;finalGCgc=newGC(image);canvas.addPaintListener(newPaintListener(){publicvoidpaintControl(PaintEventevent){event.gc.drawImage(image,0,0);}});
Thebodyoftheexamplewillcreateathreadthatiteratesthrougheachframe,waitinguntilthedelayTimehaspassed.ForeachframetheImageDataisretrievedfromtheloaderandatemporaryImagecreated.Thisisthendrawnontotheimagebeingdisplayedonthecanvas,atthexandypositionspecifiedbytheframesImageData.BecausewecreatedthetemporaryframeImagewemustdisposeitwhenitsnolongerbeingusedtofreeuptheunderlyingresource.
Threadthread=newThread(){publicvoidrun(){longcurrentTime=System.currentTimeMillis();intdelayTime=loader.data[imageNumber].delayTime;while(currentTime+delayTime*10>System.currentTimeMillis()){//Waittillthedelaytimehaspassed}display.asyncExec(newRunnable(){publicvoidrun(){//IncreasethevariableholdingtheframenumberimageNumber=imageNumber==loader.data.length-1?0:imageNumber+1;//DrawthenewdataontotheimageImageDatanextFrameData=loader.data[imageNumber];ImageframeImage=newImage(display,nextFrameData);gc.drawImage(frameImage,nextFrameData.x,nextFrameData.y);frameImage.dispose();canvas.redraw();}});}};shell.open();thread.start();
ScalingIntheexamplessofarwehaveloadedanimagefromafileanddrawnitontheGUIatitsoriginalsize.Therearetimeswhenthiswillnotalwaysbethecaseandyouneedtostretchorshrinktheimage,andtherearetwowaystodoachievethis.ThefirstistousetheGCtostretchandclipit,usingGC.drawImage(Imageimage,intsrcX,intsrcY,intsrcWidth,intsrcHeight,intdstX,intdstY,intdstWidth,intdstHeight),andthesecondistouseImageData.scaledTo(intwidth,intheight)tocreateanewImageDataobjectbasedonscalingthereceiver.
ThefollowingcodeloadstheIdea.jpgimage,andscalesthisto1/2and2timesitsoriginalsizeusingtheImageData.scaledTo(intwidth,intheight).TheimageisalsoresizedusingGC.drawImage(...),andtheexampleshowstwowaystoachievethis.Thefirsttechniqueistospecifythenewwidthandheightaspartthepaintevent.Thisispotentiallyinefficientbecausethescalingmustbedoneeachtimethecanvasrepaintsitself.Amoreoptimizedtechniqueistocreateanimageatthefinaldesiredsize,constructaGCoverthethisandthenpaintontoitsoapermanentscaledimageexistsintheprogram.
Theendresultisshownbelow,andbothtechniquesproducealmostidenticalresults.
finalImageimage=newImage(display,getClass(),getResourceAsStream("Idea.jpg"));finalintwidth=image.getBounds().width;finalintheight=image.getBounds().height;
finalImagescaled050=newImage(display,image.getImageData().scaledTo((int)(width*0.5),(int)(height*0.5)));finalImagescaled200=newImage(display,image.getImageData().scaledTo((int)(width*2),(int)(height*2)));
finalImagescaledGC200=newImage(display,(int)(width*2),(int)(height*2));GCgc=newGC(scaledGC200);gc.drawImage(image,0,0,width,height,0,0,width*2,height*2);gc.dispose();
canvas.addPaintListener(newPaintListener(){publicvoidpaintControl(PaintEvente){e.gc.drawImage(image,0,0,width,height,0,0,(int)(width*0.5),(int)(height*0.5));e.gc.drawImage(scaled050,100,0);e.gc.drawImage(scaledGC200,0,75);e.gc.drawImage(scaled200,225,175);}});
WhentouseGCscaling,andwhentouseImageData.scaledTo(...),dependsontheparticularscenario.TheGCscalingisfasterbecauseitisnative,howeveritdoesassumethatyouhaveaGCandanImagetoworkwith.UsingjusttheImageDatameansthatyoudontneedtohavepreparedanImage(thatrequiresanativeresourceandrequiresdisposing),andanImageDatacanbeloadeddirectlyfromagraphicfile(usingtheconstructorImageData(StringfileName)orImageData(InputStreamstream)).ByusingrawImageDatayouaredelayingthepointatwhichyouwillneednativedisplayresources,howeveryouwilleventuallyneedtocreateanImagefromthescaledImageDatabeforeitcanberenderedontoadevice.
CursorThefinalsectionofthisarticlecoverstheclassorg.eclipse.swt.graphics.Cursorresponsibleformanagingtheoperatingsystemresourceassociatedwiththemousepointer.Thereasoncursorsarecoveredinanarticleonimagesisbecauseyoucancreatearbitrarycursorsfromimages,andtheyillustratehowimagemaskswork.
Cursorscanbecreatedintwoways,eitherfromapre-definedstyleorusingsourceandmaskimages.
PlatformcursorsThelistofpre-definedstylesareSWTconstantsshownbelow,togetherwithsampleimagesalthoughthesewillvarydependingontheoperatingsystemandplatformsettings.CURSOR_APPSTARTINGCURSOR_IBEAMCURSOR_SIZENECURSOR_ARROWCURSOR_NOCURSOR_SIZENESWCURSOR_CROSSCURSOR_SIZEALLCURSOR_SIZENSCURSOR_HANDCURSOR_SIZEECURSOR_SIZENWCURSOR_HELPCURSOR_SIZENCURSOR_SIZESNWSECURSOR_SIZESCURSOR_SIZESECURSOR_SIZESWCURSOR_SIZEWECURSOR_UPARROWCURSOR_WAIT
EveryControlcanhaveacursorassociatedwithit,andwhenthemousepointermovesoverthecontrolitchangestothespecifiedcursor.Changingacursoralsoaffectsanychildcontrols,soifyouupdatethecursoronaShellthisaffectsthemousepointerforanywhereontheshell,althoughifthechildcontrolitselfhasanexplicitcursor,orusesitsowncursorsuchasanIbeanforTextorCombo,thistakesprecedenceovertheparentsdefinedcursor.Thefollowingcodeillustratesthis,bychangingtheshellscursortobehandcursor,andthelistscursortoacross.Whenthemouseisovertheshell(oritschildButtonthathasnoexplicitcursor)itisahand,andwhenitisoverthelistitisacross.
Listlist=newList(shell,SWT.BORDER);Buttonbutton=newButton(shell,SWT.NONE);button.setText("Button");CursorhandCursor=newCursor(display,SWT.CURSOR_HAND);shell.setCursor(handCursor);CursorcrossCursor=newCursor(display,SWT.CURSOR_CROSS);list.setCursor(crossCursor);
Cursorsuseunderlyingnativeresourcesandshouldbedisposedwhentheyarenolongerrequired.IntheabovecodethiswouldbewhentheshellhasbeendisposedandtherearenoremainingcontrolsusingeitherthehandCursororcrossCursorfields.
CustomcursorsAswellasusingapre-definedstyle,acursorcanbecreatedfromimagesusingtheconstructorCursor(Devicedevice,ImageDatasource,ImageDatamask,inthotspotx,inthotspoty).Thesourceimagedataargumentisthegraphicforthecursorshape,andthemaskisusedtospecifytransparency.Thefollowingexampleshowshowtocreateamonochromecustomcursor,wherethethesourceandmaskimagedatahaveacolordepthof1andindexedpaletteswithtwocolors.TheImageData’sheightandwidthshouldbenolargerthan32anditdoesnotnecessarilyhavetobesquare,althoughthemaskandsourceshouldbethesamesize.Thehotspotisthepointonthecursorthatrepresentsthepreciselocationofthemousepointer.
Thesourceandmaskimagedatapixelsarecombinedtodeterminewhetherthecursorpixelshouldbewhite,blackortransparent.ImageMaskCursorcolor10Transparent00Black11Black01White
TheImageDatacanbeloadedfromfiles,andEclipseitselfdoesthisforsomeofitsdraganddropcursorsdefinedinorg.eclipse.ui/icons/full/dnd.Youcanalsodirectlycreateandmanipulatetheimagedatawithinyourprogram.Thecodesamplebelowcreatesanindexedpalettewithtwocolors.ThesourceandmaskImageDataare32by32withacolordepthof1.Theint[]forthesourceandmaskdefineanuparrow,the0sforthesourceand1sforthemaskareshowninboldtoshowhowthearrowisdefinedwiththearrays.0and1makeswhitewhichisthecenterofthearrow,1and1isblackfortheedgeofthearrow,and1and0transparentfortheremainder.Thetipofthearrowis16,3sothisismadethecursorhotspotwhenitiscreated.
PaletteDatapaletteData=newPaletteData(newRGB[]{newRGB(0,0,0),newRGB(255,255,255)});ImageDatasourceData=newImageData(32,32,1,paletteData);ImageDatamaskData=newImageData(32,32,1,paletteData);
int[]cursorSource=newint[]{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int[]cursorMask=newint[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
sourceData.setPixels(0,0,1024,cursorSource,0);maskData.setPixels(0,0,1024,cursorMask,0);Cursorcursor=newCursor(display,sourceData,maskData,16,3);shell.setCursor(cursor);
Tokeepthecodelistingsnarrowtheabovesampleusedanint[]todefinethesourceandmaskimageData.Abyteuseslessmemorythananunsignedint,sowhencreatingcustomcursorsitismoreefficienttouseabyte[]instead,suchas:
byte[]cursorSource=newbyte[]{(byte)0x00,(byte)0x00,(byte)0x01,(byte)0x01,(byte)0x00,//etc...
Customcursorsneedtobedisposedinjustthesamewayaspre-definedsystemcursors,sowhenthereisnoremainingcontrolusingthecursorismustbesendthemethoddispose()tofreeuptheunderlyingnativeresource.
Althoughtheaboveexampleisforamonochromecursor,Eclipse3.0supportscolorcursorsonplatformsthatallowit(suchasWindows).TwoSWTcodesnippetsshowinghowtodothisarehere:snippet1,snippet2.
ConclusionThisarticlehasshowedhowtocreateandmanipulateSWTimages.UnderlyingeachImageisitsImageDatathatrecordsthepixelvalueforeachcoordinate,andthepalettethatmapsthistoaspecificcolor.ByunderstandingImageDataitispossibletoachieveeffectssuchastransparency,alphablending,animation,aswellascustomizedcursors.
JavaandallJava-basedtrademarksandlogosaretrademarksorregisteredtrademarksofSunMicrosystems,Inc.intheUnitedStates,othercountries,orboth.
WindowsisatrademarkofMicrosoftcorporationintheUnitedStates,othercountries,orboth.
Othercompany,product,andservicenamesmaybetrademarksorservicemarksofothers.
唉!都是钱闹的1.Swing和.net开发比较------从市场份额看.net开发主要占据大部分的中小型和中型的的桌面开发,原因是它封装了很多工具 |
|