/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * BufferedImageF.java * Copyright Remco Bouckaert remco@cs.auckland.ac.nz (C) 2011 */ package viz.graphics; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; public class BufferedImageF { // dimensions of image int m_nWidth, m_nHeight; // 255x255x255 color representation of image public BufferedImage m_localImage; // int array representation of image int [] m_nR; int [] m_nG; int [] m_nB; // flag to indicate both image representations are the same //boolean m_bInSync; /** flag to indicate drawing direction **/ boolean m_bIsHorizontal = true; // current drawing color int m_nRed; int m_nGreen; int m_nBlue; // current drawing alpha float m_fAlpha; public BufferedImageF(int nWidth, int nHeight) { m_nWidth = nWidth; m_nHeight = nHeight; m_localImage = new BufferedImage(nWidth, nHeight, BufferedImage.TYPE_4BYTE_ABGR); //System.err.println(">>>>>>>>>>>>>>>>>>>>>CREATING IMAGE" + nWidth + " " + nHeight); // m_nR = new int[nHeight][nWidth]; // m_nG = new int[nHeight][nWidth]; // m_nB = new int[nHeight][nWidth]; m_nR = new int[nHeight*nWidth]; m_nG = new int[nHeight*nWidth]; m_nB = new int[nHeight*nWidth]; //m_bInSync = true; } public int getWidth() {return m_localImage.getWidth();} public int getHeight() {return m_localImage.getHeight();} public int getRGB(int i, int j) {return m_localImage.getRGB(i, j);} /** set up background **/ public void init(Graphics2D g, Color bgColor, BufferedImage bgImage, double [] fBGImageBox, int nLabelWidth, double fMinLong, double fMaxLong, double fMinLat, double fMaxLat) { g.setBackground(bgColor); g.clearRect(0, 0, m_localImage.getWidth(), m_localImage.getHeight()); if (bgImage != null) { if (fMaxLong==180) { g.drawImage(bgImage, 0, 0, m_localImage.getWidth() - nLabelWidth - 20, m_localImage.getHeight(), 0, 0, bgImage.getWidth(), bgImage.getHeight(), null); } else { int nW = bgImage.getWidth(); int nH = bgImage.getHeight(); // int x0 =(int)(nW * (180+fMinLong)/360.0); // int x1=(int)(nW * (180+fMaxLong)/360.0); // int y0=(int)(nH * (90-fMaxLat)/180.0); // int y1=(int)(nH * (90-fMinLat)/180.0); int x0 =(int)(nW * (fMinLong- fBGImageBox[0])/(fBGImageBox[2] - fBGImageBox[0])); int x1=(int)(nW * (fMaxLong- fBGImageBox[0])/(fBGImageBox[2] - fBGImageBox[0])); int y0=(int)(nH * (fMaxLat- fBGImageBox[3])/(fBGImageBox[1] - fBGImageBox[3])); int y1=(int)(nH * (fMinLat- fBGImageBox[3])/(fBGImageBox[1] - fBGImageBox[3])); g.drawImage(bgImage, 0, 0, m_localImage.getWidth() - nLabelWidth - 20, m_localImage.getHeight(), x0, y0, x1, y1, null); if (x1 > nW) { g.drawImage(bgImage, 0, 0, m_localImage.getWidth() - nLabelWidth - 20, m_localImage.getHeight(), x0-nW, y0, x1-nW, y1, null); } } } // if (bgImage != null) { // g.drawImage(bgImage, // 0, 0, m_localImage.getWidth() - nLabelWidth - 20, m_localImage.getHeight(), // 0, 0, bgImage.getWidth(), bgImage.getHeight(), // null); // } //m_bInSync = false; } // init public void SyncIntToRGBImage() { int p = 0; for (int y = 0; y < m_nHeight; y++) { for (int x = 0; x < m_nWidth; x++) { int nRGB = m_localImage.getRGB(x, y); m_nR[p] = (nRGB & 0xFF0000); m_nG[p] = (nRGB & 0xFF00)<<8; m_nB[p] = (nRGB & 0xFF)<<16; p++; } } //m_bInSync = true; } public Graphics2D createGraphics() { return m_localImage.createGraphics(); } public void drawImage(Graphics g, Component component) { int [] rgbArray = new int [m_nWidth * m_nHeight]; int k = 0; for (int y = 0; y < m_nHeight; y++) { for (int x = 0; x < m_nWidth; x++) { int nRGB = (m_nR[k] & 0xFF0000); nRGB += (m_nG[k] & 0xFF0000)>> 8; nRGB += (m_nB[k] & 0xFF0000)>>16; rgbArray[k++] = nRGB|0xFF000000; } } m_localImage.setRGB(0, 0, m_nWidth, m_nHeight, rgbArray, 0, m_nWidth); g.drawImage(m_localImage, 0, 0, component); } public void setColor(Graphics2D g, Color color) { g.setColor(color); } public void setOrientation(boolean bIsHorizontal) { m_bIsHorizontal = bIsHorizontal; } public void scale(Graphics2D g, double fScaleX, double fScaleY) { g.scale(fScaleX, fScaleY); } // scale //Graphics2D createGraphics() {return } // return fractional part of x float fpart(float x) {return (x - (int) x);} // return 1 - fpart(x) float rfpart(float x) {return 1.0f - fpart(x);} // return ipart(x + 0.5) int round(double x) {return (int) (x+0.5);} // plot the pixel at (x, y) with brightness alpha (where 0 ≤ alpha ≤ 1) void plot(int x, int y, float fAlpha, int nRed, int nGreen, int nBlue) { if (y>=m_nHeight || x >= m_nWidth || x < 0 || y < 0) {return;} // m_nR[y][x] = (int)(m_nR[y][x]*(1-fAlpha) + nRed * fAlpha); // m_nG[y][x] = (int)(m_nG[y][x]*(1-fAlpha) + nGreen * fAlpha); // m_nB[y][x] = (int)(m_nB[y][x]*(1-fAlpha) + nBlue * fAlpha); int p = y* m_nWidth + x; m_nR[p] = (int)(m_nR[p]*(1-fAlpha) + nRed * fAlpha); m_nG[p] = (int)(m_nG[p]*(1-fAlpha) + nGreen * fAlpha); m_nB[p] = (int)(m_nB[p]*(1-fAlpha) + nBlue * fAlpha); } // void plot(int x, int y, int nRed, int nGreen, int nBlue) { // m_nR[y][x] += nRed; // m_nG[y][x] += nGreen; // m_nB[y][x] += nBlue; // } /** Line drawing using Digital Differential Analyzer or DDA for short * http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html * **/ void line(int x1, int y1, int x2, int y2, float fAlpha, int nRed, int nGreen, int nBlue, float fLineWidth) { int length,x,y,dx,dy,wx,wy,w; if(Math.abs(x2-x1)>=Math.abs(y2-y1)) { length=Math.abs(x2-x1); } else { length=Math.abs(y2-y1); } w=(int) fLineWidth; wx=(int)(((w-1)/2)*(Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))/Math.abs(y2-y1))); wy=(int)(((w-1)/2)*(Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))/Math.abs(x2-x1))); dx=(x2-x1)/length; dy=(y2-y1)/length; if(dy>dx) { wy=wx; } x=(int)(x1+(dx>0?0.5:-0.5)); y=(int)(y1+(dy>0?0.5:-0.5)); int i=1; while(i<=length) { for(int j=-wy;j<wy;j++) { plot(x,y+j, fAlpha, nRed, nGreen, nBlue); } if (wy==0) { plot(x,y, fAlpha, nRed, nGreen, nBlue); } x+=dx; y+=dy; i++; } } /** Bresenham's line drawing algorithm Jack E. Bresenham, "Algorithm for computer control of a digital plotter", IBM Systems Journal, Vol. 4, No.1, January 1965, pp. 25–30 http://www.research.ibm.com/journal/sj/041/ibmsjIVRIC.pdf */ void line2(int x0, int y0, int x1, int y1, float fAlpha, int nRed, int nGreen, int nBlue, float fLineWidth) { boolean steep = Math.abs(y1 - y0) > Math.abs(x1 - x0); if (steep) { //swap(x0, y0) int h = x0;x0 = y0; y0 = h; //swap(x1, y1) h = x1;x1 = y1; y1 = h; } if (x0 > x1) { //swap(x0, x1) //swap(y0, y1) int h = x0;x0 = x1; x1 = h; h = y0; y0 = y1; y1 = h; } int deltax = x1 - x0; int deltay = Math.abs(y1 - y0); int error = deltax / 2; int ystep; int y = y0; if (y0 < y1) { ystep = 1 ; } else { ystep = -1; } for (int x = x0; x < x1; x++) { if (steep) { for (int i = 0; i <= (int) fLineWidth; i++) { plot(y+i,x, fAlpha, nRed, nGreen, nBlue); } } else { for (int i = 0; i <= (int) fLineWidth; i++) { plot(x,y+i, fAlpha, nRed, nGreen, nBlue); } } error = error - deltay; if (error < 0) { y = y + ystep; error = error + deltax; } } } }