Graphics2D Pixel Applets

We show screenshots and code for two applets to demonstrate the drawing of individual pixels using the setRGB method of a BufferedImage. Both illustrate the Mandelbrot set and are conversions from the Pascal code for Lazarus and Delphi. These, in turn, were modifications of code from Merlin's Delphi Forge. We encourage you to experiment with the code to obtain a variety of appealing images. The value 255 for the alpha channel makes the image opaque so that it does not show any of the original background of the applet.

Even though the variable rX being assigned in the following statement is real, it is necessary to cast iI to a real (Double in this case) to force the division of iI by iMaxX to evaluate to a real number.

rX := -0.85 + 3 * Double(iI) / iMaxX;

We have already used the setRGB method for drawing pixels in the conversion of Ihsan Fazal's MultiDraw to Oxygene for Java. You can examine that code to see another way of obtaining a colour argument to pass to the method.

Mandelbrot 1

Mandelbrot 1

namespace pixel_demo1;

interface

uses
  java.applet, java.awt.*, java.util;

type
  PixelDemo = public class(Applet)
  private
    img : BufferedImage;
    iMaxX, iMaxY : Integer;
  public
    method init; override;
    method paint(g: Graphics); override;
  end;
implementation

method PixelDemo.init;
begin
  iMaxX := getSize.width;
  iMaxY := getSize.height;
  img  := new BufferedImage(Width, Height,
                            BufferedImage.TYPE_4BYTE_ABGR);
end;

method PixelDemo.paint(g: Graphics);
var
  iNewColor, iI, iJ, CurrentColour : Integer;
  g2 : Graphics2D;
  rU, rV, rX, rY, rZ : Double;
begin
  g2 := Graphics2D(g);
  for iI := 0 to iMaxX - 2 do
    begin
      for iJ := 0 to iMaxY - 2 do
        begin
          //Centre and scale along real (x) axis
          rX := -0.85 + 3 * Double(iI) / iMaxX;
          //Centre and scale along imaginary (y) axis
          rY := -1.2 + 2.4 * Double(iJ) / iMaxY;
          iNewColor := 0;
          rU := 0;
          rV := 0;
          repeat
            rZ := rU * rU - rV * rV - rX;
            rV := 2 * rU * rV - rY;
            rU := rZ;
            inc(iNewColor);
          until (rU * rU + rV * rV > 4) or (iNewColor = 1000);
          if iNewColor = 1000 then
            iNewColor := 0;
          CurrentColour:= $ff000000 + iNewColor; //Set Alpha to 255
          img.setRGB(iI, iJ, CurrentColour); //Draw a single pixel
        end;
    end;
  g2.drawImage(img, 0, 0, self);
end;

end.

The second version is much more colourful. You can change the displayed colours by changing corresponding values in the palette.

Mandelbrot 2

Mandelbrot 2


namespace pixel_demo2;

interface

uses
  java.applet, java.awt.*, java.util;

type
  PixelDemo = public class(Applet)
  private
    img : BufferedImage;
    iMaxX, iMaxY : Integer;
  public
    method init; override;
    method paint(g: Graphics); override;
  end;
implementation

method PixelDemo.init;
begin
  iMaxX := getSize.width;
  iMaxY := getSize.height;
  img  := new BufferedImage(Width, Height,
                            BufferedImage.TYPE_4BYTE_ABGR);
end;

method PixelDemo.paint(g: Graphics);
var
  iNewColor, iI, iJ, CurrentColour : Integer;
  g2 : Graphics2D;
  rU, rV, rX, rY, rZ : Double;
  Palette: array[0 .. 255] of Integer :=
      [$000000,$A80000,$00A800,$A8A800,$0000A8,$A800A8,$0054A8,$A8A8A8,
       $545454,$FC8484,$54FC54,$FCFC54,$5454FC,$FC54FC,$54FCFC,$FCFCFC,
       $000000,$141414,$202020,$2C2C2C,$383838,$444444,$505050,$606060,
       $707070,$808080,$909090,$A0A0A0,$B4B4B4,$C8C8C8,$E0E0E0,$FCFCFC,
       $FC0000,$FC0040,$FC007C,$FC00BC,$FC00FC,$BC00FC,$7C00FC,$4000FC,
       $0000FC,$0040FC,$007CFC,$00BCFC,$00FCFC,$00FCBC,$00FC7C,$00FC40,
       $00FC00,$40FC00,$7CFC00,$BCFC00,$FCFC00,$FCBC00,$FC7C00,$FC4000,
       $FC7C7C,$FC7C9C,$FC7CBC,$FC7CDC,$FC7CFC,$DC7CFC,$BC7CFC,$9C7CFC,
       $7C7CFC,$FC9CFC,$7CBCFC,$7CDCFC,$7CFCFC,$7CFCDC,$7CFCBC,$7CFC9C,
       $7CFC7C,$9CFC7C,$BCFC7C,$DCFC7C,$FCFC7C,$FCDC7C,$FCBC7C,$FC9C7C,
       $FCB4B4,$FCB4C4,$FCB4D8,$FCB4E8,$FCB4FC,$E8B4FC,$D8B4FC,$C4B4FC,
       $B4B4FC,$B4C4FC,$B4D8FC,$B4E8FC,$B4FCFC,$B4FCE8,$B4FCD8,$B4FCC4,
       $B4FCB4,$C4FCB4,$D8FCB4,$E8FCB4,$FCFCB4,$FCE8B4,$FCD8B4,$FCC4B4,
       $700000,$70001C,$700038,$700054,$700070,$540070,$380070,$1C0070,
       $000070,$001C70,$003870,$005470,$007070,$007054,$007038,$00701C,
       $007000,$1C7000,$387000,$547000,$707000,$705400,$703800,$701C00,
       $703838,$703844,$703854,$703860,$703870,$603870,$543870,$443870,
       $383870,$384470,$385470,$386070,$387070,$387060,$387054,$387044,
       $387038,$447038,$547038,$607038,$707038,$706038,$705438,$704438,
       $705050,$705058,$705060,$705068,$705070,$685070,$605070,$585070,
       $505070,$505870,$506070,$506870,$507070,$507068,$507060,$507058,
       $507050,$587050,$607050,$687050,$707050,$706850,$706050,$705850,
       $400000,$400010,$400020,$400030,$400040,$300040,$200040,$100040,
       $000040,$001040,$002040,$003040,$004040,$004030,$004020,$004010,
       $004000,$104000,$204000,$304000,$404000,$403000,$402000,$401000,
       $402020,$402028,$402030,$402038,$402040,$382040,$302040,$282040,
       $202040,$202840,$203040,$203840,$204040,$204038,$204030,$204028,
       $204020,$284020,$304020,$384020,$404020,$403820,$403020,$402820,
       $402C2C,$402C30,$402C34,$402C3C,$402C40,$3C2C40,$342C40,$302C40,
       $2C3040,$2C3440,$2C3C40,$2C4040,$2C403C,$2C4034,$2C4030,$2C402C,
       $30402C,$34402C,$3C402C,$40402C,$403C2C,$40342C,$40302C,$000000,
       $000000,$000000,$000000,$000000,$000000,$000000,$000000,$000000];
begin
  g2 := Graphics2D(g);
  for iI := 0 to iMaxX - 2 do
    begin
      for iJ := 0 to iMaxY - 2 do
        begin
          //Centre and scale along real (x) axis
          rX := -0.85 + 3 * Double(iI) / iMaxX;
          //Centre and scale along imaginary (y) axis
          rY := -1.2 + 2.4 * Double(iJ) / iMaxY;
          iNewColor := 0;
          rU := 0;
          rV := 0;
          repeat
            rZ := rU * rU - rV * rV - rX;
            rV := 2 * rU * rV - rY;
            rU := rZ;
            inc(iNewColor);
          until (rU * rU + rV * rV > 4) or (iNewColor = 255);
          if iNewColor = 255 then
            iNewColor := 0;
          CurrentColour:= $ff000000 + Palette[iNewColor]; //Set Alpha to 255
          img.setRGB(iI, iJ, CurrentColour); //Draw a single pixel
        end;
    end;
  g2.drawImage(img, 0, 0, self);
end;

end.
Programming - a skill for life!

Applets using Graphics2D for transforms, gradient painting and pixel drawing in Oxygene for Java