我的jsp页面获取了一个BufferedImage 对象,但是无法显示出来,只是显示一个红X
jsp页面代码<%@ page contentType="image/jpeg" import="java.sql.Connection,com.hb.util.*,java.awt.image.*,javax.imageio.*" pageEncoding="GBK"%>
<%
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection("jdbcdbc:"+dbname+";uid="+username+";pwd="+pwd);
// 在内存中创建图象
DrawLine dl=new DrawLine(conn,"select testTable1.标示名,testTable1.数据列1,testTable1.数据列2,testTable1.数据列3,testTable1.数据列4,testTable1.数据列5,testTable1.数据列6,testTable1.数据列7,testTable1.数据列8 from testTable1");
//设置页面不缓存
out.clearBuffer();
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
BufferedImage image =dl.drawReflexLine(20, 10, 0);
ImageIO.write(image, "JPEG", response.getOutputStream());
response.getOutputStream().flush();
} catch (Exception ex) { ex.printStackTrace(); }
%>
其中
我使用
ImageIO.write(image,format,new File("c://a.jpeg"));
就可以正确保存在C盘
所以获取BufferedImage 的过程肯定没有问题 问题就是出现在获取了BufferedImage 后如何显示 public class DrawLine { Connection conn;
String sql; Color dise = Color.white;
Color zise = Color.black;
Color tuse = Color.red;
int perHeight = 20;
int perWidth = 40; public DrawLine(Connection conn,String sql)
{
this.conn=conn;
this.sql=sql;
} //w,h表示每的格子的长宽,x表示要将哪一列作为作为每一行的显示标记
public BufferedImage drawReflexLine(int w,int h,int x){ //表查询,读取表的行列数
DataModel m = new DataModel(conn,sql);
int c =m.getColumnCount();
int r =m.getRowCount()+1; //把单元格长宽乘上行列数即为图像的长宽
h = h*r;
w = w*c; //定义一张带缓冲的图像,并为这张图像定义一个图形对象
BufferedImage image1 = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image1.createGraphics(); //这两个数组用来存放数据表中的行名和列名
int columNameN = 400,rowNameN = 400;
String columName[] = new String[columNameN];
String rowName[] = new String[rowNameN]; //读取行列名,保存在数组中
for(int i = 0;i < c;i++)
columName[i] = m.getColumnName(i);
for(int i = 0;i < (r-1);i++)
rowName[i] = m.getValueAt(i,x).toString(); //图像中的字体设置
Font f = new Font("宋体",Font.PLAIN,13);
g2.setFont(f); //此类是所有存储 2D 矩形对象的惟一抽象超类
Rectangle2D rect = new Rectangle2D.Double(0,0,w,h);
//设置底色,绘制图面
g2.setColor(dise);
g2.fill(rect);
//设置边框色,绘制图边框
g2.setColor(zise);
g2.draw(rect); //绘制行,每绘一行就在行上写入相应的行标示
//y1为每行高度,y2为当前行线的y坐标,lined为已绘的行数
//reline为真时,继续绘行线
int y1 = h/r;int y2 = 0;int lined = 0;
boolean reLine = true; while(reLine){
lined++;
y2 = y1 * lined; //绘制行线,颜色都为黑色
g2.setColor(Color.black);
Line2D line = new Line2D.Double(0,y2,w,y2);//Line2D.Double(double X1, double Y1, double X2, double Y2)
g2.draw(line); if(lined != r){
//设置字色,绘出当前行的文字,也就是表头
g2.setColor(zise);
g2.drawString(rowName[lined - 1], 0, y2 + 1 + y1);
}
if(lined == (r-1))
reLine = false;
} //绘制列,每绘一列就在列旁写入相应的列标示
//其他参数同上说明
reLine = true;lined = 0;
int x1 = w/c;int x2 = 0; while(reLine){
lined++;
x2 = x1 * lined; g2.setColor(Color.black);
Line2D line = new Line2D.Double(x2,0,x2,h);
g2.draw(line);
if(lined == 1){
//设置字色,绘制当前的列标示
g2.setColor(zise);
g2.drawString(columName[0], 0, y1);
} if(lined != c){
//设置字色,绘制当前的列标示
g2.setColor(zise);
g2.drawString(columName[lined], x2, y1);
}
if(lined == (c-1))
reLine = false;
} ////////////////////////////////////////////////////////
//////////////////////////////
//以前后两格的点为断电坐标
//以列为单位绘制折线图
String fieldTypeName;
Line2D l;
double val2 = 0,val3 = 0;
double valMax = 0;
double valMin = 0; for(int j = 1;j < c;j++){
fieldTypeName = m.getColumTypeName(j);
valMax = m.getValueAtDouble(0, j);
valMin = m.getValueAtDouble(0, j);
for(int i = 0;i<r-1;i++){
val2 = m.getValueAtDouble(i,j); if(valMax < val2)
valMax = val2;
if(valMin > val2)
valMin = val2;
}
for (int i = 0; i < r - 2; i++) {
val2 = m.getValueAtDouble(i,j);
val3 = m.getValueAtDouble(i+1,j);
val2 = (val2-valMin)/(valMax-valMin);
val3 = (val3-valMin)/(valMax-valMin);
l = new Line2D.Double(w * j / c + perWidth * val2,
h * (i + 1) / r + perHeight / 2,
w * j / c + perWidth * val3,
h * (i + 2) / r + perHeight / 2);
//设置图色
g2.setPaint(tuse);
g2.draw(l);
}
}
//g2.dispose();
return image1;
}
}
jsp页面代码<%@ page contentType="image/jpeg" import="java.sql.Connection,com.hb.util.*,java.awt.image.*,javax.imageio.*" pageEncoding="GBK"%>
<%
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection("jdbcdbc:"+dbname+";uid="+username+";pwd="+pwd);
// 在内存中创建图象
DrawLine dl=new DrawLine(conn,"select testTable1.标示名,testTable1.数据列1,testTable1.数据列2,testTable1.数据列3,testTable1.数据列4,testTable1.数据列5,testTable1.数据列6,testTable1.数据列7,testTable1.数据列8 from testTable1");
//设置页面不缓存
out.clearBuffer();
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
BufferedImage image =dl.drawReflexLine(20, 10, 0);
ImageIO.write(image, "JPEG", response.getOutputStream());
response.getOutputStream().flush();
} catch (Exception ex) { ex.printStackTrace(); }
%>
其中
我使用
ImageIO.write(image,format,new File("c://a.jpeg"));
就可以正确保存在C盘
所以获取BufferedImage 的过程肯定没有问题 问题就是出现在获取了BufferedImage 后如何显示 public class DrawLine { Connection conn;
String sql; Color dise = Color.white;
Color zise = Color.black;
Color tuse = Color.red;
int perHeight = 20;
int perWidth = 40; public DrawLine(Connection conn,String sql)
{
this.conn=conn;
this.sql=sql;
} //w,h表示每的格子的长宽,x表示要将哪一列作为作为每一行的显示标记
public BufferedImage drawReflexLine(int w,int h,int x){ //表查询,读取表的行列数
DataModel m = new DataModel(conn,sql);
int c =m.getColumnCount();
int r =m.getRowCount()+1; //把单元格长宽乘上行列数即为图像的长宽
h = h*r;
w = w*c; //定义一张带缓冲的图像,并为这张图像定义一个图形对象
BufferedImage image1 = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image1.createGraphics(); //这两个数组用来存放数据表中的行名和列名
int columNameN = 400,rowNameN = 400;
String columName[] = new String[columNameN];
String rowName[] = new String[rowNameN]; //读取行列名,保存在数组中
for(int i = 0;i < c;i++)
columName[i] = m.getColumnName(i);
for(int i = 0;i < (r-1);i++)
rowName[i] = m.getValueAt(i,x).toString(); //图像中的字体设置
Font f = new Font("宋体",Font.PLAIN,13);
g2.setFont(f); //此类是所有存储 2D 矩形对象的惟一抽象超类
Rectangle2D rect = new Rectangle2D.Double(0,0,w,h);
//设置底色,绘制图面
g2.setColor(dise);
g2.fill(rect);
//设置边框色,绘制图边框
g2.setColor(zise);
g2.draw(rect); //绘制行,每绘一行就在行上写入相应的行标示
//y1为每行高度,y2为当前行线的y坐标,lined为已绘的行数
//reline为真时,继续绘行线
int y1 = h/r;int y2 = 0;int lined = 0;
boolean reLine = true; while(reLine){
lined++;
y2 = y1 * lined; //绘制行线,颜色都为黑色
g2.setColor(Color.black);
Line2D line = new Line2D.Double(0,y2,w,y2);//Line2D.Double(double X1, double Y1, double X2, double Y2)
g2.draw(line); if(lined != r){
//设置字色,绘出当前行的文字,也就是表头
g2.setColor(zise);
g2.drawString(rowName[lined - 1], 0, y2 + 1 + y1);
}
if(lined == (r-1))
reLine = false;
} //绘制列,每绘一列就在列旁写入相应的列标示
//其他参数同上说明
reLine = true;lined = 0;
int x1 = w/c;int x2 = 0; while(reLine){
lined++;
x2 = x1 * lined; g2.setColor(Color.black);
Line2D line = new Line2D.Double(x2,0,x2,h);
g2.draw(line);
if(lined == 1){
//设置字色,绘制当前的列标示
g2.setColor(zise);
g2.drawString(columName[0], 0, y1);
} if(lined != c){
//设置字色,绘制当前的列标示
g2.setColor(zise);
g2.drawString(columName[lined], x2, y1);
}
if(lined == (c-1))
reLine = false;
} ////////////////////////////////////////////////////////
//////////////////////////////
//以前后两格的点为断电坐标
//以列为单位绘制折线图
String fieldTypeName;
Line2D l;
double val2 = 0,val3 = 0;
double valMax = 0;
double valMin = 0; for(int j = 1;j < c;j++){
fieldTypeName = m.getColumTypeName(j);
valMax = m.getValueAtDouble(0, j);
valMin = m.getValueAtDouble(0, j);
for(int i = 0;i<r-1;i++){
val2 = m.getValueAtDouble(i,j); if(valMax < val2)
valMax = val2;
if(valMin > val2)
valMin = val2;
}
for (int i = 0; i < r - 2; i++) {
val2 = m.getValueAtDouble(i,j);
val3 = m.getValueAtDouble(i+1,j);
val2 = (val2-valMin)/(valMax-valMin);
val3 = (val3-valMin)/(valMax-valMin);
l = new Line2D.Double(w * j / c + perWidth * val2,
h * (i + 1) / r + perHeight / 2,
w * j / c + perWidth * val3,
h * (i + 2) / r + perHeight / 2);
//设置图色
g2.setPaint(tuse);
g2.draw(l);
}
}
//g2.dispose();
return image1;
}
}
g2.dispose();
//输出到图像到页面
ImageIO.write(image1,"JPEG",response.getOutputStream());
如楼上所说?
g.dispose();
你为何要屏蔽掉
g.dispose();
和没加结果一样,都是出不来
...
response.reset();
...
ServletOutputStream outStream = response.getOutputStream();
com.sun.image.codec.jpeg.JPEGImageEncoder encoder =com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(outStream);
encoder.encode(image);