Java将图像像素保存到数组中&;画图
我正在做一个游戏,你只下载jar,当你下载jar时,游戏会下载新的缓存 同时,我想展示一个好的背景,而不是从链接上下载,我已经想到了这个想法,但我不确定这是否可行 每个图像都被加载并逐像素绘制,是否可以获得图像的所有像素颜色、宽度、高度,然后打印值并将其放入数组中,例如:Java将图像像素保存到数组中&;画图,java,swing,Java,Swing,我正在做一个游戏,你只下载jar,当你下载jar时,游戏会下载新的缓存 同时,我想展示一个好的背景,而不是从链接上下载,我已经想到了这个想法,但我不确定这是否可行 每个图像都被加载并逐像素绘制,是否可以获得图像的所有像素颜色、宽度、高度,然后打印值并将其放入数组中,例如: public int[] imagePixels = new int[]{PUT PIXELS HERE...}; 然后简单地用一种方法画出背景?这可能吗 有没有更好的解决方案,比如把图像打包到罐子里或者其他什么 说明: 你
public int[] imagePixels = new int[]{PUT PIXELS HERE...};
然后简单地用一种方法画出背景?这可能吗
有没有更好的解决方案,比如把图像打包到罐子里或者其他什么
说明:
你有一个图像,我想加载该图像并加载每个像素,我们从第0行开始,按宽度和高度
我想收集每个像素并将其保存到图像中,这样我就可以不使用任何文件加载图像,只需从阵列中绘制像素即可。好的,下面是您将面临的基本问题。大多数图像格式对图像数据进行某种压缩,它们还可能将有关图像的重要数据附加到文件的末尾,例如颜色模型信息,这使得在读取图像时进行渲染有些困难 您需要的是某种将图像的“块”写入文件的方法,该文件可以轻松地读回,但不会显著增加文件大小 我的测试图像从301.68KB开始,我的“块”文件格式最终为1.42MB,这让我非常不满意,直到我测试了一个最终为5.63MB的未压缩文件…我想我可以活下去了 该示例使用内置的
GZip
压缩,您可以通过以下方式获得更好的压缩
在纸上,这基本上是做什么的
- 读取像素数据块,将其写入逗号分隔的
,其中每个值都是图像中给定的像素值。该示例读取每个区块10%的文件字符串
- 然后使用
压缩对每个块进行压缩GZip
- 然后使用
编码对生成的压缩字节进行编码。就我个人而言,我更喜欢使用,因为它对内部/私有类的依赖性较小Base64
- 然后将生成的编码字符串写入一个
,并在该行末尾放置一个新行文件
- 从文件中读取一行(Base64编码的
)String
被解码(压缩为字符串
数组)字节
- 然后将
数组解压缩为逗号分隔的字节
字符串
- 然后对逗号分隔的
字符串进行
,并将生成的像素数据绘制到后备缓冲区拆分
- 生成的备份缓冲区将更新到屏幕
Image.dat
文件,而是将其保留在原来的位置,一次读取一行……这允许延迟
现在,在这个例子中,我使用了一个javax.swing.Timer
来注入一点停顿,老实说,最好使用一个SwingWorker
…但我相信你已经明白了
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ConvertImage {
public static void main(String[] args) {
try {
exportImage(new File("/path/to/your/image.jpg"), new File("Image.dat"));
} catch (IOException ex) {
ex.printStackTrace();
}
new ConvertImage();
}
public ConvertImage() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private int imgWidth = 0;
private int imgHeight = 0;
private BufferedReader br = null;
private BufferedImage imgBuffer;
private int offset;
public TestPane() {
try {
br = new BufferedReader(new FileReader(new File("Image.dat")));
String header = br.readLine();
String[] parts = header.split("x");
imgWidth = Integer.parseInt(parts[0]);
imgHeight = Integer.parseInt(parts[1]);
imgBuffer = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_ARGB);
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Graphics2D g2d = null;
try {
String text = br.readLine();
if (text != null) {
// Decode the String back to a compressed byte array
byte[] decode = Base64.decode(text);
GZIPInputStream zis = null;
try {
// Decompress the byte array
zis = new GZIPInputStream(new ByteArrayInputStream(decode));
// Build the text representation of the pixels
StringBuilder sb = new StringBuilder(128);
byte[] buffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = zis.read(buffer)) > -1) {
sb.append(new String(buffer, 0, bytesRead, "UTF-8"));
}
// Split the pixels into individual packed ints
String[] elements = sb.toString().split(",");
g2d = imgBuffer.createGraphics();
for (String element : elements) {
Point p = getPointAt(offset, imgWidth, imgHeight);
g2d.setColor(new Color(Integer.parseInt(element), true));
g2d.drawLine(p.x, p.y, p.x, p.y);
offset++;
}
g2d.dispose();
repaint();
} catch (Exception exp) {
exp.printStackTrace();
}
} else {
try {
br.close();
} catch (Exception exp) {
}
((Timer) e.getSource()).stop();
}
} catch (IOException ex) {
ex.printStackTrace();
try {
br.close();
} catch (Exception exp) {
}
((Timer) e.getSource()).stop();
} finally {
try {
g2d.dispose();
} catch (Exception exp) {
}
}
}
});
timer.start();
} catch (IOException ex) {
ex.printStackTrace();
try {
br.close();
} catch (Exception e) {
}
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(imgWidth, imgHeight);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = (getWidth() - imgBuffer.getWidth()) / 2;
int y = (getHeight() - imgBuffer.getHeight()) / 2;
g.drawImage(imgBuffer, x, y, this);
}
}
protected static void exportImage(File in, File out) throws IOException {
BufferedImage img = ImageIO.read(in);
int width = img.getWidth();
int height = img.getHeight();
// Calculate the total "length" of the image
int imageLength = width * height;
// Calculate the length of each line we will produce
// This is the number of pixels per chunk
int runLength = Math.round((width * height) * 0.1f);
// The place to write the output
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(out));
bw.write(width + "x" + height);
bw.newLine();
// Start converting the pixels...
int offset = 0;
while (offset < imageLength) {
// Calculate the size of the next buffer run, we don't want to
// over run the end of the image
int bufferSize = runLength;
if (offset + bufferSize > imageLength) {
bufferSize = imageLength - offset;
}
// Create a buffer to store the pixel results in...
StringBuilder sb = new StringBuilder(bufferSize * 2);
for (int index = 0; index < bufferSize; index++) {
Point p = getPointAt(offset + index, width, height);
if (sb.length() > 0) {
sb.append(",");
}
// Store the pixel
sb.append(img.getRGB(p.x, p.y));
}
// Write the contents to a compressed stream...
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream zos = new GZIPOutputStream(baos);
zos.write(sb.toString().getBytes());
zos.flush();
zos.close();
// Encode the compressed results to Base64
String encoded = Base64.encode(baos.toByteArray());
// Write the content...
bw.write(encoded);
bw.newLine();
// Jump to the next "chunk"
offset += bufferSize;
}
} catch (IOException exp) {
exp.printStackTrace();
} finally {
try {
bw.close();
} catch (Exception e) {
}
}
}
public static Point getPointAt(int index, int width, int height) {
Point p = new Point();
p.y = index / width;
p.x = index % width;
return p;
}
}
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.image.buffereImage;
导入java.io.BufferedReader;
导入java.io.BufferedWriter;
导入java.io.ByteArrayInputStream;
导入java.io.ByteArrayOutputStream;
导入java.io.File;
导入java.io.FileReader;
导入java.io.FileWriter;
导入java.io.IOException;
导入java.util.zip.gzip输入流;
导入java.util.zip.GZIPOutputStream;
导入javax.imageio.imageio;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.Timer;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共类图像{
公共静态void main(字符串[]args){
试一试{
exportImage(新文件(“/path/to/your/image.jpg”)、新文件(“image.dat”);
}捕获(IOEX异常){
例如printStackTrace();
}
新图像();
}
公众形象({
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}捕获(ClassNotFoundException ex){
}catch(实例化异常){
}捕获(非法访问例外){
}捕获(无支持的LookandFeelexception ex){
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(新的BorderLayout());
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
private int imgWidth=0;
私密的内部照明=0;
私有BufferedReader br=null;
私有缓存映像imgBuffer;
私有整数偏移;
公共测试窗格(){
试一试{
br=新的BufferedReader(新文件读取器(新文件(“Image.dat”));
字符串头=br.readLine();
String[]parts=header.split(“x”);
imgWidth=In