📄 imgmod02.java
字号:
package com.ynstudio.image;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
class ImgMod02 extends Frame{
Image rawImg;
int imgCols;//Number of horizontal pixels
int imgRows;//Number of rows of pixels
Image modImg;//Reference to modified image
//Inset values for the Frame
int inTop;
int inLeft;
//Default image-processing program. This
// program will be executed to process the
// image if the name of another program is not
// entered on the command line. Note that the
// class file for this program is included in
// this source code file.
static String theProcessingClass =
"com.ynstudio.image.WaveIt";
//Default image file name. This image file
// will be processed if another file name is
// not entered on the command line. You must
// provide this file in the current directory.
static String theImgFile = "d:/testxx.jpg";
MediaTracker tracker;
Display display = new Display();//A Canvas
Button replotButton = new Button("Replot");
//References to arrays that store pixel data.
int[][][] threeDPix;
int[][][] threeDPixMod;
int[] oneDPix;
//Reference to the image-processing object.
ImgIntfc02 imageProcessingObject;
//-------------------------------------------//
public static void main(String[] args){
//Get names for the image-processing program
// and the image file to be processed.
// Program supports gif files and jpg files
// and possibly some other file types as
// well.
if(args.length == 0){
//Use default processing class and default
// image file. No code required here.
// Class and file names were specified
// above. This case is provided for
// information purposes only.
}else if(args.length == 1){
theProcessingClass = args[0];
//Use default image file
}else if(args.length == 2){
theProcessingClass = args[0];
theImgFile = args[1];
}else{
System.out.println("Invalid args");
System.exit(1);
}//end else
//Display name of processing program and
// image file.
System.out.println("Processing program: "
+ theProcessingClass);
System.out.println("Image file: "
+ theImgFile);
//Instantiate an object of this class
ImgMod02 obj = new ImgMod02();
}//end main
//-------------------------------------------//
public ImgMod02(){//constructor
//Get an image from the specified file. Can
// be in a different directory if the path
// was entered with the file name on the
// command line.
rawImg = (new ImageProducer()).createFontImg("redapple");
//rawImg = Toolkit.getDefaultToolkit().
//getImage(theImgFile);
//Use a MediaTracker object to block until
// the image is loaded or ten seconds has
// elapsed.
tracker = new MediaTracker(this);
tracker.addImage(rawImg,1);
try{
if(!tracker.waitForID(1,10000)){
System.out.println("Load error.");
System.exit(1);
}//end if
}catch(InterruptedException e){
e.printStackTrace();
System.exit(1);
}//end catch
//Make certain that the file was successfully
// loaded.
if((tracker.statusAll(false)
& MediaTracker.ERRORED
& MediaTracker.ABORTED) != 0){
System.out.println(
"Load errored or aborted");
System.exit(1);
}//end if
//Raw image has been loaded. Get width and
// height of the raw image.
imgCols = rawImg.getWidth(this);
imgRows = rawImg.getHeight(this);
this.setTitle("Copyright 2004, Baldwin");
this.setBackground(Color.YELLOW);
this.add(display);
this.add(replotButton,BorderLayout.SOUTH);
//Make it possible to get insets and the
// height of the button.
setVisible(true);
//Get and store inset data for the Frame and
// the height of the button.
inTop = this.getInsets().top;
inLeft = this.getInsets().left;
int buttonHeight =
replotButton.getSize().height;
//Size the frame so that a small amount of
// yellow background will show on the right
// and on the bottom when both images are
// displayed, one above the other. Also, the
// placement of the images on the Canvas
// causes a small amount of background to
// show between the images.
this.setSize(2*inLeft+imgCols + 1,inTop
+ buttonHeight + 2*imgRows + 7);
//=========================================//
//Anonymous inner class listener for replot
// button. This actionPerformed method is
// invoked when the user clicks the Replot
// button. It is also invoked at startup
// when this program posts an ActionEvent to
// the system event queue attributing the
// event to the Replot button.
replotButton.addActionListener(
new ActionListener(){
public void actionPerformed(
ActionEvent e){
//Pass a 3D array of pixel data to the
// processing object and get a modified
// 3D array of pixel data back. The
// creation of the 3D array of pixel
// data is explained later.
threeDPixMod =
imageProcessingObject.processImg(
threeDPix,imgRows,imgCols);
//Convert the modified pixel data to a
// 1D array of pixel data. The 1D
// array is explained later.
oneDPix = convertToOneDim(
threeDPixMod,imgCols,imgRows);
//Use the createImage() method to
// create a new image from the 1D array
// of pixel data.
modImg = createImage(
new MemoryImageSource(
imgCols,imgRows,oneDPix,0,imgCols));
//Repaint the image display frame with
// the original image at the top and
// the modified pixel data at the
// bottom.
Graphics g = display.getGraphics();
//((java.awt.Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
display.repaint();
}//end actionPerformed
}//end ActionListener
);//end addActionListener
//End anonymous inner class.
//=========================================//
//Create a 1D array object to receive the
// pixel representation of the image
oneDPix = new int[imgCols * imgRows];
//Convert the rawImg to numeric pixel
// representation. Note that grapPixels()
// throws InterruptedException
try{
//Instantiate a PixelGrabber object
// specifying oneDPix as the array in which
// to put the numeric pixel data. See Sun
// docs for parameters
PixelGrabber pgObj = new PixelGrabber(//这里应该是关键。获取图片里的象素。
rawImg,0,0,imgCols,imgRows,
oneDPix,0,imgCols);
//Invoke the grabPixels() method on the
// PixelGrabber object to extract the pixel
// data from the image into an array of
// numeric pixel data stored in oneDPix.
// Also test for success in the process.
boolean x = pgObj.grabPixels();
System.out.println("pgObj.grabPixels() = "+x);
int status = pgObj.getStatus();
System.out.println("status= "+ status);
// if(x &&
// ((status &
// ImageObserver.ALLBITS)
// != 0)){
if(x){
//Convert the pixel byte data in the 1D
// array to int data in a 3D array to
// make it easier to work with the pixel
// data later. Recall that pixel data is
// unsigned byte data and Java does not
// support unsigned arithmetic.
// Performing unsigned arithmetic on byte
// data is particularly cumbersome.
threeDPix = convertToThreeDim(
oneDPix,imgCols,imgRows);
//Instantiate a new object of the image
// processing class. Note that this
// object is instantiated using the
// newInstance method of the class named
// Class. This approach does not support
// the use of a parameterized
// constructor.
try{
imageProcessingObject = (
ImgIntfc02)Class.forName(
theProcessingClass).newInstance();
//Post counterfeit ActionEvent to the
// system event queue and attribute it
// to the Replot button. (See the
// anonymous ActionListener class
// defined above that registers an
// ActionListener object on the RePlot
// button.) Posting this event causes
// the image-processing method to be
// invoked, passing the 3D array of
// pixel data to the method, and
// receiving a 3D array of modified
// pixel data back from the method.
Toolkit.getDefaultToolkit().
getSystemEventQueue().postEvent(
new ActionEvent(
replotButton,
ActionEvent.ACTION_PERFORMED,
"Replot"));
//At this point, the image has been
// processed and both the original
// image and the modified image
// have been displayed. From this
// point forward, each time the user
// clicks the Replot button, the image
// will be processed again and the new
// modified image will be displayed
// along with the original image.
}catch(Exception e){
e.printStackTrace();
}//end catch
}//end if statement on grabPixels
else System.out.println(
"Pixel grab not successful");
}catch(InterruptedException e){
e.printStackTrace();
}//end catch
//Cause the composite of the frame, the
// canvas, and the button to become visible.
this.setVisible(true);
//=========================================//
//Anonymous inner class listener to terminate
// program.
this.addWindowListener(
new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);//terminate the program
}//end windowClosing()
}//end WindowAdapter
);//end addWindowListener
//=========================================//
}//end constructor
//===========================================//
//Inner class for canvas object on which to
// display the two images.
class Display extends Canvas{
//Override the paint method to display both
// the rawImg and the modImg on the same
// Canvas object, separated by one row of
// pixels in the background color.
public void paint(Graphics g){
//First confirm that the image has been
// completely loaded and neither image
// reference is null.
if (tracker.statusID(1, false) ==
MediaTracker.COMPLETE){
if((rawImg != null) &&
(modImg != null)){
g.drawImage(rawImg,0,0,this);
g.drawImage(modImg,0,imgRows + 1,this);
}//end if
}//end if
}//end paint()
}//end class myCanvas
//=============================================//
//Save pixel values as type int to make
// arithmetic easier later.
//The purpose of this method is to convert the
// data in the int oneDPix array into a 3D
// array of ints.
//The dimensions of the 3D array are row,
// col, and color in that order.
//Row and col correspond to the rows and
// columns of the image. Color corresponds to
// transparency and color information at the
// following index levels in the third
// dimension:
// 0 alpha
// 1 red
// 2 green
// 3 blue
// The structure of this code is determined by
// the way that the pixel data is formatted
// into the 1D array of ints produced by the
// grabPixels method of the PixelGrabber
// object.
int[][][] convertToThreeDim(
int[] oneDPix,int imgCols,int imgRows){
//Create the new 3D array to be populated
// with color data.
int[][][] data =
new int[imgRows][imgCols][4];
for(int row = 0;row < imgRows;row++){
//Extract a row of pixel data into a
// temporary array of ints
int[] aRow = new int[imgCols];
for(int col = 0; col < imgCols;col++){
int element = row * imgCols + col;
aRow[col] = oneDPix[element];
}//end for loop on col
//Move the data into the 3D array. Note
// the use of bitwise AND and bitwise right
// shift operations to mask all but the
// correct set of eight bits.
for(int col = 0;col < imgCols;col++){
//Alpha data
data[row][col][0] = (aRow[col] >> 24)
& 0xFF;
//Red data
data[row][col][1] = (aRow[col] >> 16)
& 0xFF;
//Green data
data[row][col][2] = (aRow[col] >> 8)
& 0xFF;
//Blue data
data[row][col][3] = (aRow[col])
& 0xFF;
}//end for loop on col
}//end for loop on row
return data;
}//end convertToThreeDim
//-------------------------------------------//
//The purpose of this method is to convert the
// data in the 3D array of ints back into the
// 1d array of type int. This is the reverse
// of the method named convertToThreeDim.
int[] convertToOneDim(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -