00001 package com.meapsoft.gui;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 import java.awt.Color;
00024 import java.awt.Dimension;
00025 import java.awt.Graphics;
00026 import java.awt.Image;
00027 import java.awt.image.BufferedImage;
00028 import java.awt.image.FilteredImageSource;
00029 import java.awt.image.ImageFilter;
00030 import java.awt.image.ImageObserver;
00031 import java.awt.image.ReplicateScaleFilter;
00032 import java.util.Arrays;
00033
00034 import javax.swing.JPanel;
00035
00036
00041 public class SpectrogramPanel extends JPanel {
00045 private BufferedImage spectrogram = null;
00046
00050 private Image scaledSpectrogram = null;
00051
00055 private float zoom = 1.0f;
00056 private float vzoom = 1.0f;
00057
00062 private double offsetFactor;
00063
00067 private double[][] data;
00068
00069 private int width;
00070 private int height;
00071
00072 private ColorMap cmap = ColorMap.getJet(64);
00073
00074
00075 private double minVal;
00076 private double maxVal;
00077
00081 public SpectrogramPanel(double[][] dat) {
00082 data = dat;
00083 width = dat.length;
00084 height = dat[0].length;
00085
00086
00087
00088
00089
00090 computeSpectrogram();
00091 }
00092
00096 private void computeSpectrogram() {
00097 try {
00098
00099 maxVal = 0;
00100 minVal = Integer.MAX_VALUE;
00101 for(int x = 0; x < width; x++)
00102 {
00103 for(int y = 0; y < height; y++)
00104 {
00105 if (data[x][y] > maxVal)
00106 maxVal = data[x][y];
00107 if (data[x][y] < minVal)
00108 minVal = data[x][y];
00109 }
00110 }
00111 double minIntensity = Math.abs(minVal);
00112 double maxIntensity = maxVal + minIntensity;
00113
00114 int maxYIndex = height - 1;
00115 Dimension d = new Dimension(width, height);
00116
00117 setMinimumSize(d);
00118 setMaximumSize(d);
00119 setPreferredSize(d);
00120
00121
00122
00123 spectrogram = new BufferedImage(width,
00124 height,
00125 BufferedImage.TYPE_INT_RGB);
00126
00127
00128
00129
00130 double scaleFactor = ((0x3f + offsetFactor) / maxIntensity);
00131
00132 for (int i = 0; i < width; i++) {
00133 for (int j = maxYIndex; j >= 0; j--) {
00134
00135
00136
00137
00138 int grey = (int)((data[i][j] + minIntensity) * scaleFactor
00139 - offsetFactor);
00140
00141
00142
00143 spectrogram.setRGB(i, maxYIndex - j, cmap.getColor(grey));
00144 }
00145 }
00146
00147 ImageFilter scaleFilter =
00148 new ReplicateScaleFilter((int) (zoom * width), (int)(vzoom*height));
00149 scaledSpectrogram =
00150 createImage(new FilteredImageSource(spectrogram.getSource(),
00151 scaleFilter));
00152 Dimension sz = getSize();
00153 repaint(0, 0, 0, sz.width - 1, sz.height - 1);
00154 } catch (Exception e) {
00155 e.printStackTrace();
00156 }
00157 }
00158
00168 public void setOffsetFactor(double offsetFactor) {
00169 this.offsetFactor = offsetFactor;
00170 computeSpectrogram();
00171 }
00172
00177 protected void vzoomSet(float vzoom) {
00178 this.vzoom = vzoom;
00179 zoom();
00180 }
00181
00186 protected void hzoomSet(float zoom) {
00187 zoomSet(zoom);
00188 }
00189
00194 protected void zoomSet(float zoom) {
00195 this.zoom = zoom;
00196 zoom();
00197 }
00198
00199 private void zoom()
00200 {
00201 if (spectrogram != null)
00202 {
00203 int width = spectrogram.getWidth();
00204 int height = spectrogram.getHeight();
00205
00206
00207 width = (int) (zoom * width);
00208 height = (int)(vzoom*height);
00209
00210 ImageFilter scaleFilter =
00211 new ReplicateScaleFilter(width, height);
00212 scaledSpectrogram =
00213 createImage(new FilteredImageSource(spectrogram.getSource(),
00214 scaleFilter));
00215
00216
00217 setPreferredSize(new Dimension(width, height));
00218 revalidate();
00219
00220 repaint();
00221 }
00222 }
00223
00224 public float getVZoom()
00225 {
00226 return vzoom;
00227 }
00228
00229 public float getHZoom()
00230 {
00231 return zoom;
00232 }
00233
00234 public SpectrogramPanel getColorBar()
00235 {
00236 int barWidth = 20;
00237
00238 double[][] cb = new double[barWidth][cmap.size];
00239
00240 for(int x = 0; x < cb.length; x++)
00241 for(int y = 0; y < cb[x].length; y++)
00242 cb[x][y] = y;
00243
00244 return new SpectrogramPanel(cb);
00245 }
00246
00247 public double getData(int x, int y)
00248 {
00249 return data[x][y];
00250 }
00251
00252 public int getDataWidth()
00253 {
00254 return width;
00255 }
00256
00257 public int getDataHeight()
00258 {
00259 return height;
00260 }
00261
00262
00268 public void paint(Graphics g) {
00272 Dimension sz = getSize();
00273
00274 g.setColor(Color.WHITE);
00275 g.fillRect(0, 0, sz.width - 1, sz.height - 1);
00276
00277 if(spectrogram != null) {
00278 g.drawImage(scaledSpectrogram, 0, 0, (ImageObserver) null);
00279 }
00280 }
00281 }