- added a method for the RasterPlotter to draw arrow endings to lines

- replaced the dot in the NetworkGraph with arrows
- enhanced the image drawing speed using pre-computed color values
- added more attention for OOM cases during very large image painting
pull/1/head
Michael Peter Christen 12 years ago
parent 342543a6c4
commit d5d64019e5

@ -87,7 +87,11 @@ public class AccessPicture_p {
// draw home peer
final int centerx = (picture.gridWidth() >> 1) - 1;
final int centery = picture.gridHeight() >> 1;
picture.setColor(color_dot);
long color_dot_l = Long.parseLong(color_dot, 16);
long color_text_l = Long.parseLong(color_text, 16);
long color_line_l = Long.parseLong(color_line, 16);
long color_grid_l = Long.parseLong(color_grid, 16);
picture.setColor(color_dot_l);
picture.gridDot(centerx, centery, 5, true, 100);
if (corona) {
for (int i = 0; i < 6; i++) {
@ -97,7 +101,7 @@ public class AccessPicture_p {
picture.gridDot(centerx, centery, 50, false, 100);
}
//picture.gridDot(centerx, centery, 31, false);
picture.setColor(color_text);
picture.setColor(color_text_l);
picture.gridPrint(centerx, centery, 5, "THIS YACY PEER", "\"" + sb.peers.myName().toUpperCase() + "\"", 0);
// left column: collect data for access from outside
@ -128,10 +132,10 @@ public class AccessPicture_p {
// draw left column: access from outside
for (int i = 0; i < hosts.length; i++) {
if (hosts[i] != null) {
picture.setColor(color_dot);
picture.setColor(color_dot_l);
picture.gridDot(gridLeft, i * 2 + 1, 7, false, 100);
picture.gridDot(gridLeft, i * 2 + 1, 8, false, 100);
picture.setColor(color_text);
picture.setColor(color_text_l);
picture.gridPrint(gridLeft, i * 2 + 1, 8, hosts[i].toUpperCase(), "COUNT = " + count[i] + ", TIME > " + ((time[i] >= 60000) ? ((time[i] / 60000) + " MINUTES") : ((time[i] / 1000) + " SECONDS")), -1);
if (corona) {
picture.gridLine((centerx - gridLeft) / 2 - 2, i * 2 + 1, gridLeft, i * 2 + 1,
@ -139,7 +143,7 @@ public class AccessPicture_p {
picture.gridLine(centerx, centery, (centerx - gridLeft) / 2 - 2, i * 2 + 1,
color_line, 100, "AAAAAA", 100, 12, 11 - coronaangle / 30, 0, true);
} else {
picture.setColor(color_line);
picture.setColor(color_line_l);
picture.gridLine(gridLeft, i * 2 + 1, (centerx - gridLeft) / 2, i * 2 + 1);
picture.gridLine(centerx, centery, (centerx - gridLeft) / 2, i * 2 + 1);
}
@ -163,10 +167,10 @@ public class AccessPicture_p {
// draw right column: access to outside
for (int i = 0; i < hosts.length; i++) {
if (hosts[i] != null) {
picture.setColor(color_dot);
picture.setColor(color_dot_l);
picture.gridDot(gridRight, i * 2 + 1, 7, false, 100);
picture.gridDot(gridRight, i * 2 + 1, 8, false, 100);
picture.setColor(color_text);
picture.setColor(color_text_l);
picture.gridPrint(gridRight, i * 2 + 1, 8, hosts[i].toUpperCase(), count[i] + " BYTES, " + time[i] + " MS DUE", 1);
if (corona) {
picture.gridLine(gridRight, i * 2 + 1, centerx + (gridRight - centerx) / 2 + 2, i * 2 + 1,
@ -174,7 +178,7 @@ public class AccessPicture_p {
picture.gridLine(centerx, centery, centerx + (gridRight - centerx) / 2 + 2, i * 2 + 1,
color_line, 100, "AAAAAA", 100, 12, coronaangle / 30, 0, true);
} else {
picture.setColor(color_line);
picture.setColor(color_line_l);
picture.gridLine(gridRight, i * 2 + 1, centerx + (gridRight - centerx) / 2, i * 2 + 1);
picture.gridLine(centerx, centery, centerx + (gridRight - centerx) / 2, i * 2 + 1);
}
@ -182,24 +186,24 @@ public class AccessPicture_p {
}
// print headline
picture.setColor(color_text);
picture.setColor(color_text_l);
PrintTool.print(picture, 2, 6, 0, "YACY NODE ACCESS GRID", -1);
PrintTool.print(picture, width - 2, 6, 0, "SNAPSHOT FROM " + new Date().toString().toUpperCase(), 1);
// print legend
picture.setColor(color_grid);
picture.setColor(color_grid_l);
picture.gridLine(gridLeft, 0, centerx - 3, 0);
picture.gridLine(gridLeft, 0, gridLeft, picture.gridHeight() - 1);
picture.gridLine(centerx - 3, 0, centerx - 3, picture.gridHeight() - 1);
picture.setColor(color_dot);
picture.setColor(color_dot_l);
picture.gridLine(gridLeft, picture.gridHeight() - 1, centerx - 3, picture.gridHeight() - 1);
picture.gridPrint(gridLeft, picture.gridHeight() - 1, 8, "", "INCOMING CONNECTIONS", -1);
picture.setColor(color_grid);
picture.setColor(color_grid_l);
picture.gridLine(centerx + 3, 0, gridRight, 0);
picture.gridLine(centerx + 3, 0, centerx + 3, picture.gridHeight() - 1);
picture.gridLine(gridRight, 0, gridRight, picture.gridHeight() - 1);
picture.setColor(color_dot);
picture.setColor(color_dot_l);
picture.gridLine(centerx + 3, picture.gridHeight() - 1, gridRight, picture.gridHeight() - 1);
picture.gridPrint(gridRight, picture.gridHeight() - 1, 8, "", "OUTGOING CONNECTIONS", 1);

@ -139,7 +139,7 @@ public class WebStructurePicture_p {
graphPicture = graph.draw(width, height, 40, 40, 16, 16, 12, 6, color_back, color_dot0, color_dota, color_line, color_lineend, color_text);
}
// print headline
graphPicture.setColor(color_text);
graphPicture.setColor(Long.parseLong(color_text, 16));
PrintTool.print(graphPicture, 2, 8, 0, "YACY WEB-STRUCTURE ANALYSIS", -1);
if (hosts != null) PrintTool.print(graphPicture, 2, 16, 0, "LINK ENVIRONMENT OF DOMAIN " + hosts.toUpperCase(), -1);
PrintTool.print(graphPicture, width - 2, 8, 0, "SNAPSHOT FROM " + new Date().toString().toUpperCase(), 1);

@ -46,7 +46,7 @@ public class imagetest {
img.dot(620, 200, 90, true, 100);
img.setColor(RasterPlotter.RED);
img.arc(300, 270, 30, 70, 100);
img.setColor("330000");
img.setColor(Long.parseLong("330000", 16));
img.arc(220, 110, 50, 90, 30, 110);
img.arc(210, 120, 50, 90, 30, 110);
img.setColor(RasterPlotter.GREY);
@ -57,7 +57,7 @@ public class imagetest {
img.setColor(i);
img.dot(10 + 14 * (int) (i / 16), 200 + 14 * (int) (i % 16), 6, true, 100);
}
img.setColor("008000");
img.setColor(Long.parseLong("008000", 16));
img.dot(10 + 14 * 8, 200 + 14 * 8, 90, true, 100);
/*
for (long r = 0; r < 256; r = r + 16) {
@ -68,9 +68,9 @@ public class imagetest {
}
}
}*/
img.setColor("0000A0");
img.setColor(Long.parseLong("0000A0", 16));
img.arc(550, 400, 40, 81, 100);
img.setColor("010100");
img.setColor(Long.parseLong("010100", 16));
for (int i = 0; i <= 360; i++) {
img.arc(550, 400, 40, 41 + i/9, 0, i);
}

@ -461,7 +461,7 @@ final class memprofiler extends Thread {
int seconds0 = 0, kilobytes0 = 0;
int seconds1 = 0, kilobytes1 = 0;
while (this.run) {
this.memChart.setColor("FF0000");
this.memChart.setColor(Long.parseLong("FF0000", 16));
seconds1 = (int) ((System.currentTimeMillis() - this.start) / 1000);
kilobytes1 = (int) (MemoryControl.used() / 1024);
this.memChart.chartLine(ChartPlotter.DIMENSION_BOTTOM, ChartPlotter.DIMENSION_LEFT, seconds0, kilobytes0, seconds1, kilobytes1);

@ -79,7 +79,7 @@ public final class Banner {
final int width = data.getWidth();
// draw description
bannerPicture.setColor(data.getTextcolor());
bannerPicture.setColor(Long.parseLong(data.getTextcolor(), 16));
PrintTool.print(bannerPicture, 100, 12, 0, "PEER: " + addTrailingBlanks(data.getName(), exprlength), -1);
PrintTool.print(bannerPicture, 100, 22, 0, "LINKS: " + addBlanksAndDots(data.getLinks(), exprlength), -1);
PrintTool.print(bannerPicture, 100, 32, 0, "WORDS: " + addBlanksAndDots(data.getWords(), exprlength), -1);
@ -100,7 +100,7 @@ public final class Banner {
final String bordercolor = data.getBordercolor();
if (bordercolor != null && !bordercolor.isEmpty()) {
bannerPicture.setColor(bordercolor);
bannerPicture.setColor(Long.parseLong(bordercolor, 16));
bannerPicture.line(0, 0, 0, height - 1, 100);
bannerPicture.line(0, 0, width - 1, 0, 100);
bannerPicture.line(width - 1, 0, width - 1, height - 1, 100);

@ -193,7 +193,7 @@ public class NetworkGraph {
final int outerradius = maxradius - 20;
// draw network circle
networkPicture.setColor(COL_DHTCIRCLE);
networkPicture.setColor(Long.parseLong(COL_DHTCIRCLE, 16));
networkPicture.arc(width / 2, height / 2, innerradius - 20, innerradius + 20, 100);
//System.out.println("Seed Maximum distance is " + yacySeed.maxDHTDistance);
@ -301,7 +301,7 @@ public class NetworkGraph {
}
// draw description
networkPicture.setColor(COL_HEADLINE);
networkPicture.setColor(Long.parseLong(COL_HEADLINE, 16));
PrintTool.print(networkPicture, 2, 6, 0, "YACY NETWORK '" + networkName.toUpperCase() + "'", -1);
PrintTool.print(networkPicture, 2, 14, 0, networkTitle.toUpperCase(), -1);
PrintTool.print(networkPicture, width - 2, 6, 0, "SNAPSHOT FROM " + new Date().toString().toUpperCase(), 1);
@ -317,12 +317,13 @@ public class NetworkGraph {
final int angleMy = cyc + (int) (360.0d * Distribution.horizontalDHTPosition(ASCII.getBytes(mySeed.hash)) / DOUBLE_LONG_MAX_VALUE);
final int angleOther = cyc + (int) (360.0d * Distribution.horizontalDHTPosition(ASCII.getBytes(otherSeed.hash)) / DOUBLE_LONG_MAX_VALUE);
// draw line
Long colorLine_l = Long.parseLong(colorLine, 16);
img.arcLine(centerX, centerY, innerradius, innerradius - 20, angleMy, !out,
colorLine, null, 12, (coronaangle < 0) ? -1 : coronaangle / 30, 2, true);
colorLine_l, null, 12, (coronaangle < 0) ? -1 : coronaangle / 30, 2, true);
img.arcLine(centerX, centerY, innerradius, innerradius - 20, angleOther, out,
colorLine, null, 12, (coronaangle < 0) ? -1 : coronaangle / 30, 2, true);
colorLine_l, null, 12, (coronaangle < 0) ? -1 : coronaangle / 30, 2, true);
img.arcConnect(centerX, centerY, innerradius - 20, angleMy, angleOther, out,
colorLine, 100, null, 100, 12, (coronaangle < 0) ? -1 : coronaangle / 30, 2, true);
colorLine_l, 100, null, 100, 12, (coronaangle < 0) ? -1 : coronaangle / 30, 2, true);
}
private static class drawNetworkPicturePeerJob {
@ -364,12 +365,12 @@ public class NetworkGraph {
if (this.colorDot.equals(COL_MYPEER_DOT)) dotsize = dotsize + 4;
if (dotsize > 18) dotsize = 18;
// draw dot
this.img.setColor(this.colorDot);
this.img.setColor(Long.parseLong(this.colorDot, 16));
this.img.arcDot(this.centerX, this.centerY, this.innerradius, angle, dotsize);
// draw line to text
this.img.arcLine(this.centerX, this.centerY, this.innerradius + 18, this.innerradius + linelength, angle, true, this.colorLine, "444444", 12, this.coronaangle / 30, 0, true);
this.img.arcLine(this.centerX, this.centerY, this.innerradius + 18, this.innerradius + linelength, angle, true, Long.parseLong(this.colorLine, 16), Long.parseLong("444444", 16), 12, this.coronaangle / 30, 0, true);
// draw text
this.img.setColor(this.colorText);
this.img.setColor(Long.parseLong(this.colorText, 16));
PrintTool.arcPrint(this.img, this.centerX, this.centerY, this.innerradius + linelength, angle, name);
// draw corona around dot for crawling activity

@ -121,9 +121,9 @@ public class ProfilingGraph {
bytes = ((Long) event.payload).longValue();
x1 = (int) (time/1000);
y1 = (int) (bytes / 1024 / 1024);
chart.setColor("AAAAFF");
chart.setColor(Long.parseLong("AAAAFF", 16));
chart.chartDot(ChartPlotter.DIMENSION_BOTTOM, ChartPlotter.DIMENSION_RIGHT, x1, y1, 2, null, 0);
chart.setColor("0000FF");
chart.setColor(Long.parseLong("0000FF", 16));
if (x0 < 0) chart.chartLine(ChartPlotter.DIMENSION_BOTTOM, ChartPlotter.DIMENSION_RIGHT, x0, y0, x1, y1);
x0 = x1; y0 = y1;
}
@ -142,9 +142,9 @@ public class ProfilingGraph {
words = (int) ((Long) event.payload).longValue();
x1 = (int) (time/1000);
y1 = words;
chart.setColor("228822");
chart.setColor(Long.parseLong("228822", 16));
chart.chartDot(ChartPlotter.DIMENSION_BOTTOM, ChartPlotter.DIMENSION_LEFT, x1, y1, 2, null, 315);
chart.setColor("008800");
chart.setColor(Long.parseLong("008800", 16));
if (x0 < 0) chart.chartLine(ChartPlotter.DIMENSION_BOTTOM, ChartPlotter.DIMENSION_LEFT, x0, y0, x1, y1);
x0 = x1; y0 = y1;
}
@ -162,9 +162,9 @@ public class ProfilingGraph {
ppm = (int) ((Long) event.payload).longValue();
x1 = (int) (time/1000);
y1 = ppm;
chart.setColor("AA8888");
chart.setColor(Long.parseLong("AA8888", 16));
if (x0 < 0) chart.chartLine(ChartPlotter.DIMENSION_BOTTOM, ChartPlotter.DIMENSION_ANOT0, x0, y0, x1, y1);
chart.setColor("AA2222");
chart.setColor(Long.parseLong("AA2222", 16));
chart.chartDot(ChartPlotter.DIMENSION_BOTTOM, ChartPlotter.DIMENSION_ANOT0, x1, y1, 2, ppm + " PPM", 0);
x0 = x1; y0 = y1;
}
@ -184,7 +184,7 @@ public class ProfilingGraph {
x1 = (int) (time/1000);
y1 = Math.abs((ping.outgoing ? ping.toPeer : ping.fromPeer).hashCode()) % vspace;
pingPeer = ping.outgoing ? "-> " + ping.toPeer.toUpperCase() : "<- " + ping.fromPeer.toUpperCase();
chart.setColor("444444");
chart.setColor(Long.parseLong("444444", 16));
chart.chartDot(ChartPlotter.DIMENSION_BOTTOM, ChartPlotter.DIMENSION_ANOT2, x1, y1, 2, pingPeer + (ping.newPeers > 0 ? "(+" + ping.newPeers + ")" : ""), 0);
x0 = x1; y0 = y1;
}

@ -31,6 +31,9 @@ import java.io.IOException;
import javax.imageio.ImageIO;
import net.yacy.kelondro.logging.Log;
import net.yacy.kelondro.util.ByteBuffer;
public class ChartPlotter extends RasterPlotter {
@ -66,11 +69,11 @@ public class ChartPlotter extends RasterPlotter {
//this.backgroundColor = backgroundColor;
//this.foregroundColor = foregroundColor;
if (name != null) {
this.setColor(foregroundColor);
if (foregroundColor != null) this.setColor(Long.parseLong(foregroundColor, 16));
PrintTool.print(this, width / 2 - name.length() * 3, 6, 0, name, -1);
}
if (subline != null) {
this.setColor(lightColor);
if (lightColor != null) this.setColor(Long.parseLong(lightColor, 16));
PrintTool.print(this, width / 2 - subline.length() * 3, 14, 0, subline, -1);
}
}
@ -110,18 +113,20 @@ public class ChartPlotter extends RasterPlotter {
final int y = (top) ? this.topborder : this.height - this.bottomborder;
int x = this.leftborder;
int s = offset;
Long colorScale_l = colorScale == null ? null : Long.parseLong(colorScale, 16);
Long colorNaming_l = colorNaming == null ? null : Long.parseLong(colorNaming, 16);
while (x < this.width - this.rightborder) {
if ((colorScale != null) && (x > this.leftborder) && (x < (this.width - this.rightborder))) {
setColor(colorScale);
setColor(colorScale_l);
line(x, this.topborder, x, this.height - this.bottomborder, 100);
}
setColor(colorNaming);
setColor(colorNaming_l);
line(x, y - 3, x, y + 3, 100);
PrintTool.print(this, x, (top) ? y - 3 : y + 9, 0, Integer.toString(s), -1);
x += pixelperscale;
s += scale;
}
setColor(colorNaming);
setColor(colorNaming_l);
PrintTool.print(this, this.width - this.rightborder, (top) ? y - 9 : y + 15, 0, name, 1);
line(this.leftborder - 4, y, this.width - this.rightborder + 4, y, 100);
}
@ -134,12 +139,14 @@ public class ChartPlotter extends RasterPlotter {
int s = offset;
String s1;
int s1max = 0;
Long colorScale_l = colorScale == null ? null : Long.parseLong(colorScale, 16);
Long colorNaming_l = colorNaming == null ? null : Long.parseLong(colorNaming, 16);
while (y > this.topborder) {
if ((colorScale != null) && (y > this.topborder) && (y < (this.height - this.bottomborder))) {
setColor(colorScale);
setColor(colorScale_l);
line(this.leftborder, y, this.width - this.rightborder, y, 100);
}
setColor(colorNaming);
setColor(colorNaming_l);
line(x - 3, y, x + 3, y, 100);
s1 = (s >= 1000000 && s % 10000 == 0) ? Integer.toString(s / 1000000) + "M" : (s >= 1000 && s % 1000 == 0) ? Integer.toString(s / 1000) + "K" : Integer.toString(s);
if (s1.length() > s1max) s1max = s1.length();
@ -147,7 +154,7 @@ public class ChartPlotter extends RasterPlotter {
y -= pixelperscale;
s += scale;
}
setColor(colorNaming);
setColor(colorNaming_l);
PrintTool.print(this, (left) ? x - s1max * 6 - 6 : x + s1max * 6 + 9, this.topborder, 90, name, 1);
line(x, this.topborder - 4, x, this.height - this.bottomborder + 4, 100);
}
@ -164,10 +171,10 @@ public class ChartPlotter extends RasterPlotter {
//ip.declareDimension(DIMENSION_TOP, 10, 40, "000000", null, "count");
ip.declareDimension(DIMENSION_LEFT, 50, 40, 0, green, scale , "PPM [PAGES/MINUTE]");
ip.declareDimension(DIMENSION_RIGHT, 100, 20, 0, blue, scale, "MEMORY/MEGABYTE");
ip.setColor(green);
ip.setColor(Long.parseLong(green, 16));
ip.chartDot(DIMENSION_BOTTOM, DIMENSION_LEFT, -160, 100, 5, null, 0);
ip.chartLine(DIMENSION_BOTTOM, DIMENSION_LEFT, -160, 100, -130, 200);
ip.setColor(blue);
ip.setColor(Long.parseLong(blue, 16));
ip.chartDot(DIMENSION_BOTTOM, DIMENSION_RIGHT, -50, 300, 2, null, 0);
ip.chartLine(DIMENSION_BOTTOM, DIMENSION_RIGHT, -80, 100, -50, 300);
//ip.print(100, 100, 0, "TEXT", true);
@ -177,10 +184,11 @@ public class ChartPlotter extends RasterPlotter {
final File file = new File("/Users/admin/Desktop/testimage.png");
try {
final FileOutputStream fos = new FileOutputStream(file);
ImageIO.write(ip.getImage(), "png", fos);
fos.write(RasterPlotter.exportImage(ip.getImage(), "png").getBytes());
//ImageIO.write(ip.getImage(), "png", fos);
fos.close();
} catch (final IOException e) {}
Log.shutdown();
}
}

@ -319,22 +319,27 @@ public class GraphPlotter implements Cloneable {
String name;
Point c;
int x, y;
Long color_dot0_l = Long.parseLong(color_dot0, 16);
Long color_dota_l = Long.parseLong(color_dota, 16);
Long color_line_l = Long.parseLong(color_line, 16);
Long color_lineend_l = Long.parseLong(color_lineend, 16);
Long color_text_l = Long.parseLong(color_text, 16);
while (i.hasNext()) {
entry = i.next();
name = entry.getKey();
c = entry.getValue();
x = (xfactor == 0.0) ? raster(width / 2, xraster) : leftborder + raster((c.x - this.leftmost) * xfactor, xraster);
y = (yfactor == 0.0) ? raster(height / 2, yraster) : height - bottomborder - raster((c.y - this.bottommost) * yfactor, yraster);
image.setColor(c.layer == 0 ? color_dot0 : color_dota);
image.setColor(c.layer == 0 ? color_dot0_l : color_dota_l);
image.dot(x, y, 6, true, 100);
image.setColor(color_text);
image.setColor(color_text_l);
PrintTool.print(image, x, y + 10, 0, name.toUpperCase(), 0 /*x < 2 * width / 5 ? 1 : x > 3 * width / 5 ? -1 : 0*/);
}
// draw lines
final Iterator<String> j = this.edges.iterator();
Point[] border;
image.setColor(color_line);
image.setColor(color_line_l);
int x0, x1, y0, y1;
while (j.hasNext()) {
border = getEdge(j.next());
@ -353,8 +358,8 @@ public class GraphPlotter implements Cloneable {
y0 = height - bottomborder - raster((border[0].y - this.bottommost) * yfactor, yraster);
y1 = height - bottomborder - raster((border[1].y - this.bottommost) * yfactor, yraster);
}
// draw the line, with the dot at the beginning of the line
image.lineDot(x1, y1, x0, y0, 3, 4, color_line, color_lineend);
// draw the line, with an errow at the end of the line
image.lineArrow(x0, y0, x1, y1, 6, 5, color_line_l, color_lineend_l);
}
return image;
}

@ -64,7 +64,7 @@ public class HexGridPlotter extends RasterPlotter {
}
public void drawGrid(final String colorNaming) {
setColor(colorNaming);
setColor(Long.parseLong(colorNaming, 16));
int x0, y0, x1, y1;
for (int i = 0; i < this.gwidth; i++) {
x0 = projectionX(i, -1);
@ -133,14 +133,16 @@ public class HexGridPlotter extends RasterPlotter {
int y1 = projectionY(By);
int horizontal;
int dotc = 0;
Long colorLine_l = colorLine == null ? null : Long.parseLong(colorLine, 16);
Long colorDot_l = colorDot == null ? null : Long.parseLong(colorDot, 16);
while (x1 != x0 || y1 != y0) {
horizontal = 0;
if (x1 > x0) {x1--; horizontal++;} else if (x1 < x0) {x1++; horizontal++;}
if (y1 > y0) {y1--; horizontal++;} else if (y1 < y0) {y1++; horizontal++;}
if (colorLine != null) this.setColor(colorLine);
if (colorLine != null) this.setColor(colorLine_l);
plot(x1, y1, (horizontal == 2) ? intensityLine : intensityLine * 8 / 10);
if (dotc == dotPos) {
if (colorDot != null) this.setColor(colorDot);
if (colorDot != null) this.setColor(colorDot_l);
if (dotRadius == 0) this.plot(x1, y1, intensityDot);
else if (dotRadius > 0) this.dot(x1, y1, dotRadius, dotFilled, intensityDot);
}
@ -155,17 +157,17 @@ public class HexGridPlotter extends RasterPlotter {
final HexGridPlotter picture = new HexGridPlotter(640, 480, DrawMode.MODE_SUB, "FFFFFF", 18);
picture.drawGrid("555555");
picture.setColor("33ff33");
picture.setColor(Long.parseLong("33ff33", 16));
picture.gridDot(0, 0, 5, true, 100); picture.gridPrint(0, 0, 5, "", "0,0", -1);
for (int i = 1; i < picture.gridHeight() -1; i++) {
picture.setColor("33ff33");picture.gridDot(0, i, 3, true, 100);
picture.setColor("334433");picture.gridPrint(0, i, 3, "", "0," + i, -1);
picture.setColor(Long.parseLong("33ff33", 16));picture.gridDot(0, i, 3, true, 100);
picture.setColor(Long.parseLong("334433", 16));picture.gridPrint(0, i, 3, "", "0," + i, -1);
}
for (int i = 1; i < picture.gridWidth() -1; i++) {
picture.setColor("33ff33");picture.gridDot(i, 0, 3, true, 100);
picture.setColor("334433");picture.gridPrint315(i, 0, 3, i + ",0");
picture.setColor(Long.parseLong("33ff33", 16));picture.gridDot(i, 0, 3, true, 100);
picture.setColor(Long.parseLong("334433", 16));picture.gridPrint315(i, 0, 3, i + ",0");
}
picture.setColor("33ff33");
picture.setColor(Long.parseLong("33ff33", 16));
picture.gridDot(0, picture.gheight - 1, 5, true, 100); picture.gridPrint(0, picture.gheight - 1, 5, "0, grid.gheight - 1", "", -1);
picture.gridDot(picture.gwidth - 1, 0, 5, true, 100); picture.gridPrint(picture.gwidth - 1, 0, 5, "", "grid.gwidth - 1, 0", -1);
picture.gridDot(picture.gwidth - 1, picture.gheight - 1, 5, true, 100); picture.gridPrint(picture.gwidth - 1, picture.gheight - 1, 5, "grid.gwidth - 1, grid.gheight - 1", "", 1);

@ -81,7 +81,7 @@ public class PngEncoder extends Object {
final int width = image.getWidth(null);
final int height = image.getHeight(null);
final TreeMap<Integer, ScanLines> scan = new TreeMap<Integer, ScanLines>();
final TreeMap<Integer, byte[]> scan = new TreeMap<Integer, byte[]>();
if (height > 80) {
// prepare an input list for concurrent PixelGrabber computation
final BlockingQueue<int[]> grabberInput = new LinkedBlockingQueue<int[]>();
@ -95,7 +95,7 @@ public class PngEncoder extends Object {
}
// do the PixelGrabber computation and allocate the result in the right order
ArrayList<Thread> ts = new ArrayList<Thread>();
int tc = Math.min(grabberInput.size() / 40, Runtime.getRuntime().availableProcessors());
int tc = Math.max(2, Math.min(1 + grabberInput.size() / 40, Runtime.getRuntime().availableProcessors()));
for (int i = 0; i < tc; i++) {
grabberInput.add(POISON_IN);
Thread t = new Thread() {
@ -126,9 +126,7 @@ public class PngEncoder extends Object {
final Deflater scrunch = new Deflater(compressionLevel);
ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024);
final DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes, scrunch);
for (Map.Entry<Integer, ScanLines> entry: scan.entrySet()) {
compBytes.write(entry.getValue().scan, 0, entry.getValue().count);
}
for (Map.Entry<Integer, byte[]> entry: scan.entrySet()) compBytes.write(entry.getValue());
compBytes.close();
final byte[] compressedLines = outBytes.toByteArray();
outBytes.close();
@ -171,28 +169,23 @@ public class PngEncoder extends Object {
return offset + data.length;
}
private final static void pixelGrabber(final Image image, final int width, int y, int nRows, TreeMap<Integer, ScanLines> scan) throws IOException {
private final static void pixelGrabber(final Image image, final int width, int y, int nRows, TreeMap<Integer, byte[]> scan) throws IOException {
int[] pixels = new int[width * nRows];
PixelGrabber pg = new PixelGrabber(image, 0, y, width, nRows, pixels, 0, width);
try {pg.grabPixels();} catch (InterruptedException e) {throw new IOException("interrupted waiting for pixels!");}
if ((pg.getStatus() & ImageObserver.ABORT) != 0) throw new IOException("image fetch aborted or errored");
byte[] scanLines = new byte[width * nRows * 4]; // the scan lines to be compressed
int scanPos = 0; // where we are in the scan lines
for (int i = 0; i < width * nRows; i++) {
if (i % width == 0) scanLines[scanPos++] = (byte) 0;
scanLines[scanPos++] = (byte) ((pixels[i] >> 16) & 0xff);
scanLines[scanPos++] = (byte) ((pixels[i] >> 8) & 0xff);
scanLines[scanPos++] = (byte) ((pixels[i]) & 0xff);
}
synchronized (scan) {scan.put(y, new ScanLines(scanLines, scanPos));}
}
private static class ScanLines {
protected byte[] scan;
protected int count;
public ScanLines(final byte[] scan, final int count) {
this.scan = scan;
this.count = count;
try {
ByteArrayOutputStream scanLines = new ByteArrayOutputStream(width * nRows * 3 + width);
for (int i = 0; i < width * nRows; i++) {
if (i % width == 0) scanLines.write(0);
scanLines.write((pixels[i] >> 16) & 0xff);
scanLines.write((pixels[i] >> 8) & 0xff);
scanLines.write((pixels[i]) & 0xff);
}
synchronized (scan) {scan.put(y, scanLines.toByteArray());}
scanLines.close();
} catch (OutOfMemoryError e) {
throw new IOException("out of memory, needed bytes: " + width * nRows * 4);
}
}

@ -69,7 +69,7 @@ public class RasterPlotter {
protected final int width, height;
private final int[] cc;
private BufferedImage image;
private BufferedImage image;
private final WritableRaster grid;
private int defaultColR, defaultColG, defaultColB;
private final long backgroundCol;
@ -90,9 +90,23 @@ public class RasterPlotter {
this.defaultMode = drawMode;
try {
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
/*
byte[] frame = new byte[width * height * 3];
DataBuffer videoBuffer = new DataBufferByte(frame, frame.length);
ComponentSampleModel sampleModel = new ComponentSampleModel(DataBuffer.TYPE_BYTE, width, height, 3, width*3, new int[] {2,1,0});
Raster raster = Raster.createRaster(sampleModel, videoBuffer, null);
this.image.setData(raster);
*/
} catch (final OutOfMemoryError e) {
this.image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
//throw new RuntimeException(RasterPlotter.class.getSimpleName() + ": not enough memory (" + MemoryControl.available() + ") available");
try {
this.image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED);
} catch (final OutOfMemoryError ee) {
try {
this.image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
} catch (final OutOfMemoryError eee) {
this.image = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY);
}
}
}
clear();
this.grid = this.image.getRaster();
@ -156,10 +170,6 @@ public class RasterPlotter {
}
public void setColor(final String s) {
setColor(Long.parseLong(s, 16));
}
public void plot(final int x, final int y) {
plot(x, y, 100);
}
@ -229,8 +239,8 @@ public class RasterPlotter {
public void line(
int Ax, int Ay, final int Bx, final int By,
final String colorLine, final int intensityLine,
final String colorDot, final int intensityDot, final int dotDist, final int dotPos, final int dotRadius, final boolean dotFilled
final Long colorLine, final int intensityLine,
final Long colorDot, final int intensityDot, final int dotDist, final int dotPos, final int dotRadius, final boolean dotFilled
) {
// Bresenham's line drawing algorithm
int dX = Math.abs(Bx-Ax);
@ -287,33 +297,77 @@ public class RasterPlotter {
}
}
public void lineDot(final int x0, final int y0, final int x1, final int y1, final int radius, final int distance, final String lineColor, final String dotColor) {
lineDot(x0, y0, x1, y1, radius, distance, Long.parseLong(lineColor, 16), Long.parseLong(dotColor, 16));
/**
* draw a line with a dot at the end
* @param x0 start point
* @param y0 start point
* @param x1 end point
* @param y1 end point
* @param radius radius of the dot
* @param padding the distance of the dot border to the end point
* @param lineColor the color of the line
* @param dotColor the color of the dot
*/
public void lineDot(final int x0, final int y0, final int x1, final int y1, final int radius, final int padding, final long lineColor, final long dotColor) {
final double dx = x1 - x0; // distance of points, x component
final double dy = y1 - y0; // distance of points, y component
final double angle = Math.atan2(dy, dx); // the angle of the line between the points
final double d = Math.sqrt((dx * dx + dy * dy)); // the distance between the points (Pythagoras)
final double ddotcenter = d - radius - padding; // distance from {x0, y0} to dot center near {x1, y1}
final double ddotborder = ddotcenter - radius; // distance to point {x3, y3} at border of dot center at {x2, y2}
final double xn = Math.cos(angle); // normalized vector component x
final double yn = Math.sin(angle); // normalized vector component y
final int x2 = x0 + ((int) (ddotcenter * xn)); // dot center, x component
final int y2 = y0 + ((int) (ddotcenter * yn)); // dot center, y component
final int x3 = x0 + ((int) (ddotborder * xn)); // dot border, x component
final int y3 = y0 + ((int) (ddotborder * yn)); // dot border, y component
setColor(lineColor); line(x0, y0, x3, y3, 100); // draw line from {x0, y0} to dot border
setColor(dotColor); dot(x2, y2, radius, true, 100); // draw dot at {x2, y2}
}
public void lineDot(final int x0, final int y0, final int x1, final int y1, final int radius, final int distance, final long lineColor, final long dotColor) {
// draw a line with a dot at the end.
// the radius value is the radius of the dot
// the distance value is the distance of the dot border to the endpoint
// compute first the angle of the line between the points
final double angle = (x1 - x0 > 0) ? Math.atan(((double) (y0 - y1)) / ((double) (x1 - x0))) : Math.PI - Math.atan(((double) (y0 - y1)) / ((double) (x0 - x1)));
// now find two more points in between
// first calculate the radius' of the points
final double ra = Math.sqrt(((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1))); // from a known point x1, y1
final double rb = ra - radius - distance;
final double rc = rb - radius;
// the points are on a circle with radius rb and rc
final int x2 = x0 + ((int) (rb * Math.cos(angle)));
final int y2 = y0 - ((int) (rb * Math.sin(angle)));
final int x3 = x0 + ((int) (rc * Math.cos(angle)));
final int y3 = y0 - ((int) (rc * Math.sin(angle)));
/**
* draw a line with an arrow at the end
* @param x0 start point
* @param y0 start point
* @param x1 end point
* @param y1 end point
* @param sidelength the side length of the arrow tip (all 3 sides are equal)
* @param padding the distance of the arrow tip to the end point
* @param lineColor the color of the line
* @param arrowColor the color of the arrow tip
*/
public void lineArrow(final int x0, final int y0, final int x1, final int y1, final int sidelength, final int padding, final long lineColor, final long arrowColor) {
final double dx = x1 - x0; // distance of points, x component
final double dy = y1 - y0; // distance of points, y component
final double angle = Math.atan2(dy, dx); // the angle of the line between the points
final double d = Math.sqrt((dx * dx + dy * dy)); // the distance between the points (Pythagoras)
final double arrowtip = d - padding; // the distance from {x0, y0} to the arrow tip
final double arrowlength = TL * sidelength; // the length of the arrow (distance from base to tip)
final double arrowbase = arrowtip - arrowlength; // the distance from {x0, y0} to the arrow base
final double xn = Math.cos(angle); // normalized vector component x
final double yn = Math.sin(angle); // normalized vector component y
final int xt = x0 + ((int) (arrowtip * xn)); // arrow tip point component x
final int yt = y0 + ((int) (arrowtip * yn)); // arrow tip point component y
final double xb = x0 + arrowbase * xn; // arrow base point component x
final double yb = y0 + arrowbase * yn; // arrow base point component y
final double sl2 = sidelength / 2.0; // half of the side length
final double xk = sl2 * Math.cos(angle + PI2); // point at 90 degree on arrow direction to left side, vector component x
final double yk = sl2 * Math.sin(angle + PI2); // point at 90 degree on arrow direction to left side, vector component y
final int x2 = (int) (xb + xk);
final int y2 = (int) (yb + yk);
final int x3 = (int) (xb - xk);
final int y3 = (int) (yb - yk);
setColor(lineColor);
line(x0, y0, x3, y3, 100);
setColor(dotColor);
dot(x2, y2, radius, true, 100);
line(x0, y0, (int) xb, (int) yb, 100); // draw line from {x0, y0} to arrow base
setColor(arrowColor);
line(x2, y2, x3, y3, 100); // base line
line(x2, y2, xt, yt, 100); // left line
line(x3, y3, xt, yt, 100); // right line
}
private final static double TL = Math.sqrt(3) / 2;
private final static double PI2 = Math.PI / 2;
public int[] getColor(final int x, final int y) {
final int[] c = new int[3];
return this.grid.getPixel(x, y, c);
@ -342,7 +396,7 @@ public class RasterPlotter {
}
public void arcLine(final int cx, final int cy, final int innerRadius, final int outerRadius, final double angle, final boolean in,
final String colorLine, final String colorDot, final int dotDist, final int dotPos, final int dotRadius, final boolean dotFilled) {
final Long colorLine, final Long colorDot, final int dotDist, final int dotPos, final int dotRadius, final boolean dotFilled) {
final double a = PI180 * angle;
final double cosa = Math.cos(a);
final double sina = Math.sin(a);
@ -374,8 +428,8 @@ public class RasterPlotter {
}
public void arcConnect(final int cx, final int cy, final int arcRadius, final double angle1, final double angle2, final boolean in,
final String colorLine, final int intensityLine,
final String colorDot, final int intensityDot, final int dotDist, final int dotPos, final int dotRadius, final boolean dotFilled) {
final Long colorLine, final int intensityLine,
final Long colorDot, final int intensityDot, final int dotDist, final int dotPos, final int dotRadius, final boolean dotFilled) {
final double a1 = PI180 * angle1;
final double a2 = PI180 * angle2;
final int x1 = cx + (int) (arcRadius * Math.cos(a1));

Loading…
Cancel
Save