问题
I have written a class to read the BMP files with all the necessary headers as stated here "http://www.ece.ualberta.ca/~elliott/ee552/studentAppNotes/2003_w/misc/bmp_file_format/bmp_file_format.htm"
The class reads all the necessary headers and for the raw data, it reads them as bytes as shown below -
private byte[] calcBytes(String path) throws IOException {
//Get the path of the file
Path file_path = Paths.get(path);
//Return the byte array of the file
return Files.readAllBytes(file_path);
}
Following this, I convert the bytes(stored as little-endian) values to the decimal equivalent and store them as pixel(RGB) values in an array(size: width*height) as shown below.
private int[][] calcPixels(byte[] bytes){
//Find padding, if divisible by 4
int padding = this.width % 4;
//If not divisible by 4, find the closest next that is divisible
if(padding != 0){
//Find closest bigger padding number divisible by 4
while ((padding % 4) != 0){
padding++;
}
}
//Output Pixel array store the pixel values[R,G,B] format
int[][] output_pixels = new int[((this.width + padding) * this.height)][3];
//Initialize the cols(column) of the pixel data as zero
int col = 0;
//Position to fill the output pixel array in correct index
int pos = 0;
//Iterate through the bytes array
for (int index = 0; index < bytes.length; index += 3){
//Increment the col
col++;
//Bytes to hex
String blue_hex = String.format("%02X", bytes[index]);
String green_hex = String.format("%02X", bytes[index+1]);
String red_hex = String.format("%02X", bytes[index+2]);
//Hex to int/short values
short blue = (short) Integer.parseInt(blue_hex, 16);
short green = (short) Integer.parseInt(green_hex, 16);
short red = (short) Integer.parseInt(red_hex, 16);
//Adding to the main array
output_pixels[pos++] = new int[] {red, green, blue};
//Increment Padding with at last column
if(col == (this.width+padding)/4){
//Skip the bytes since it is the padding
index += padding;
//Denote the end of the row or last column[RGB] as [-1,-1,-1], reset the value of the last stored pixel
output_pixels[pos - 1] = new int[] {(short)-1, (short)-1, (short)-1};
//Row will change now
col = 0;
}
}
return output_pixels;
}
Having generated the pixel array with necessary RGB data. I then use JavaFX to generate the pixel represented by a Rectangle shape class and giving it a when iterating through the pixel data array as generated above.
@Override
public void start(Stage primaryStage) throws Exception{
Button button = new Button("Select Image File");
String path = System.getProperty("user.dir") + "/filePath/image.bmp";
//Reads the BMP file and generate headers, bytes and pixels as shown above
BMP bmp = new BMP(path);
//Initialize the root
Group root = new Group();
int[][] pixelsData = bmp.getPixelsData();
//X (to manipulate the x coordinate of the pixel i.e. rectangle shape class)
double xFactor = 1.0;
double startX = 0.0;
double endX = startX + xFactor;
//Y (to manipulate the x coordinate of the pixel i.e. rectangle shape class)
double yFactor = 0.5;
double startY = 0.0;
double endY = startY + yFactor;
for (int index = 0; index < pixelsData.length; index++){
//Get Colors
int red = pixelsData[index][0];
int green = pixelsData[index][1];
int blue = pixelsData[index][2];
if(red == -1 && green == -1 && blue == -1){
//Start Next Line
startY += yFactor;
endY += yFactor;
startX = 0.0;
endX = startX + xFactor;
continue;
}
else {//keep moving the x coordinate
startX += xFactor;
endX += xFactor;
}
Color color = Color.rgb(red,green,blue);
Rectangle rectangle = new Rectangle(startX,startY,endX,endY);
rectangle.setFill(color);
root.getChildren().add(rectangle);
}
primaryStage.setScene(new Scene(root, 700, 700));
primaryStage.show();
}
Now when I actually generate the image with the code above. The image seems to blur out towards the end of the x-axis and also misses a lot of pixels in on the sides. Example as shown below:
Original Image
JavaFX Image
I also reversed the iteration of my JavaFX pixel data loop in order to generate the image in the right order but no luck.
If you look closely at the original image and the two JavaFX images, it is evident that the left and right side of the "cat" in the pictures is printed fine but blurs out only because of the co-ordinate in my opinion.
I have spent 2 days trying to figure it out but I am really confused. Can someone please help out with my understanding or point out any mistake I might be committing in my code.
来源:https://stackoverflow.com/questions/62625348/javafx-writing-bmp-image-pixel-by-pixel