jpeg 彩色图像压缩dct java代码实现
时间: 2023-10-26 20:08:40 浏览: 116
java代码实现图片压缩
好的,这里是一个简单的 Java 代码实现 JPEG 彩色图像压缩的过程:
```java
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class JPEGCompressor {
private static final int BLOCK_SIZE = 8;
private static final double[][] QUANTIZATION_MATRIX = {
{16, 11, 10, 16, 24, 40, 51, 61},
{12, 12, 14, 19, 26, 58, 60, 55},
{14, 13, 16, 24, 40, 57, 69, 56},
{14, 17, 22, 29, 51, 87, 80, 62},
{18, 22, 37, 56, 68, 109, 103, 77},
{24, 35, 55, 64, 81, 104, 113, 92},
{49, 64, 78, 87, 103, 121, 120, 101},
{72, 92, 95, 98, 112, 100, 103, 99}
};
public static void main(String[] args) throws IOException {
BufferedImage image = ImageIO.read(new File("input.jpg"));
int width = image.getWidth();
int height = image.getHeight();
int[][][] pixels = new int[height][width][3];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int rgb = image.getRGB(x, y);
pixels[y][x][0] = (rgb >> 16) & 0xFF;
pixels[y][x][1] = (rgb >> 8) & 0xFF;
pixels[y][x][2] = rgb & 0xFF;
}
}
int[][][] ycbcr = RGBToYCbCr(pixels);
int[][][] dct = DCTTransform(ycbcr);
int[][][] quantized = Quantization(dct);
int[][][] dequantized = Dequantization(quantized);
int[][][] idct = IDCTTransform(dequantized);
int[][][] output = YCbCrToRGB(idct);
BufferedImage compressedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int r = output[y][x][0];
int g = output[y][x][1];
int b = output[y][x][2];
int rgb = (r << 16) | (g << 8) | b;
compressedImage.setRGB(x, y, rgb);
}
}
ImageIO.write(compressedImage, "jpg", new File("output.jpg"));
}
private static int[][][] RGBToYCbCr(int[][][] pixels) {
int height = pixels.length;
int width = pixels[0].length;
int[][][] ycbcr = new int[height][width][3];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int r = pixels[y][x][0];
int g = pixels[y][x][1];
int b = pixels[y][x][2];
int yValue = (int) (0.299 * r + 0.587 * g + 0.114 * b);
int cbValue = (int) (-0.1687 * r - 0.3313 * g + 0.5 * b + 128);
int crValue = (int) (0.5 * r - 0.4187 * g - 0.0813 * b + 128);
ycbcr[y][x][0] = yValue;
ycbcr[y][x][1] = cbValue;
ycbcr[y][x][2] = crValue;
}
}
return ycbcr;
}
private static int[][][] YCbCrToRGB(int[][][] pixels) {
int height = pixels.length;
int width = pixels[0].length;
int[][][] rgb = new int[height][width][3];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int yValue = pixels[y][x][0];
int cbValue = pixels[y][x][1];
int crValue = pixels[y][x][2];
int r = (int) (yValue + 1.402 * (crValue - 128));
int g = (int) (yValue - 0.34414 * (cbValue - 128) - 0.71414 * (crValue - 128));
int b = (int) (yValue + 1.772 * (cbValue - 128));
rgb[y][x][0] = r;
rgb[y][x][1] = g;
rgb[y][x][2] = b;
}
}
return rgb;
}
private static int[][][] DCTTransform(int[][][] pixels) {
int height = pixels.length;
int width = pixels[0].length;
int[][][] dct = new int[height][width][3];
for (int y = 0; y < height; y += BLOCK_SIZE) {
for (int x = 0; x < width; x += BLOCK_SIZE) {
for (int c = 0; c < 3; c++) {
double[][] block = new double[BLOCK_SIZE][BLOCK_SIZE];
for (int j = 0; j < BLOCK_SIZE; j++) {
for (int i = 0; i < BLOCK_SIZE; i++) {
block[j][i] = pixels[y + j][x + i][c];
}
}
double[][] transformedBlock = DCT(block);
for (int j = 0; j < BLOCK_SIZE; j++) {
for (int i = 0; i < BLOCK_SIZE; i++) {
dct[y + j][x + i][c] = (int) transformedBlock[j][i];
}
}
}
}
}
return dct;
}
private static int[][][] IDCTTransform(int[][][] dct) {
int height = dct.length;
int width = dct[0].length;
int[][][] idct = new int[height][width][3];
for (int y = 0; y < height; y += BLOCK_SIZE) {
for (int x = 0; x < width; x += BLOCK_SIZE) {
for (int c = 0; c < 3; c++) {
double[][] block = new double[BLOCK_SIZE][BLOCK_SIZE];
for (int j = 0; j < BLOCK_SIZE; j++) {
for (int i = 0; i < BLOCK_SIZE; i++) {
block[j][i] = dct[y + j][x + i][c];
}
}
double[][] transformedBlock = IDCT(block);
for (int j = 0; j < BLOCK_SIZE; j++) {
for (int i = 0; i < BLOCK_SIZE; i++) {
idct[y + j][x + i][c] = (int) transformedBlock[j][i];
}
}
}
}
}
return idct;
}
private static double[][] DCT(double[][] block) {
int n = block.length;
double[][] transformedBlock = new double[n][n];
for (int v = 0; v < n; v++) {
for (int u = 0; u < n; u++) {
double sum = 0.0;
for (int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
sum += block[j][i] * Math.cos((2 * i + 1) * u * Math.PI / (2 * n)) *
Math.cos((2 * j + 1) * v * Math.PI / (2 * n));
}
}
double cu = u == 0 ? 1.0 / Math.sqrt(2) : 1.0;
double cv = v == 0 ? 1.0 / Math.sqrt(2) : 1.0;
transformedBlock[v][u] = 0.25 * cu * cv * sum;
}
}
return transformedBlock;
}
private static double[][] IDCT(double[][] block) {
int n = block.length;
double[][] transformedBlock = new double[n][n];
for (int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
double sum = 0.0;
for (int v = 0; v < n; v++) {
for (int u = 0; u < n; u++) {
double cu = u == 0 ? 1.0 / Math.sqrt(2) : 1.0;
double cv = v == 0 ? 1.0 / Math.sqrt(2) : 1.0;
sum += cu * cv * block[v][u] *
Math.cos((2 * i + 1) * u * Math.PI / (2 * n)) *
Math.cos((2 * j + 1) * v * Math.PI / (2 * n));
}
}
transformedBlock[j][i] = 0.25 * sum;
}
}
return transformedBlock;
}
private static int[][][] Quantization(int[][][] dct) {
int height = dct.length;
int width = dct[0].length;
int[][][] quantized = new int[height][width][3];
for (int y = 0; y < height; y += BLOCK_SIZE) {
for (int x = 0; x < width; x += BLOCK_SIZE) {
for (int c = 0; c < 3; c++) {
int[][] block = new int[BLOCK_SIZE][BLOCK_SIZE];
for (int j = 0; j < BLOCK_SIZE; j++) {
for (int i = 0; i < BLOCK_SIZE; i++) {
block[j][i] = dct[y + j][x + i][c];
}
}
int[][] quantizedBlock = Quantize(block, QUANTIZATION_MATRIX);
for (int j = 0; j < BLOCK_SIZE; j++) {
for (int i = 0; i < BLOCK_SIZE; i++) {
quantized[y + j][x + i][c] = quantizedBlock[j][i];
}
}
}
}
}
return quantized;
}
private static int[][][] Dequantization(int[][][] quantized) {
int height = quantized.length;
int width = quantized[0].length;
int[][][] dequantized = new int[height][width][3];
for (int y = 0; y < height; y += BLOCK_SIZE) {
for (int x = 0; x < width; x += BLOCK_SIZE) {
for (int c = 0; c < 3; c++) {
int[][] block = new int[BLOCK_SIZE][BLOCK_SIZE];
for (int j = 0; j < BLOCK_SIZE; j++) {
for (int i = 0; i < BLOCK_SIZE; i++) {
block[j][i] = quantized[y + j][x + i][c];
}
}
int[][] dequantizedBlock = Dequantize(block, QUANTIZATION_MATRIX);
for (int j = 0; j < BLOCK_SIZE; j++) {
for (int i = 0; i < BLOCK_SIZE; i++) {
dequantized[y + j][x + i][c] = dequantizedBlock[j][i];
}
}
}
}
}
return dequantized;
}
private static int[][] Quantize(int[][] block, double[][] quantizationMatrix) {
int n = block.length;
int[][] quantizedBlock = new int[n][n];
for (int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
quantizedBlock[j][i] = (int) Math.round(block[j][i] / quantizationMatrix[j][i]);
}
}
return quantizedBlock;
}
private static int[][] Dequantize(int[][] block, double[][] quantizationMatrix) {
int n = block.length;
int[][] dequantizedBlock = new int[n][n];
for (int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
dequantizedBlock[j][i] = (int) Math.round(block[j][i] * quantizationMatrix[j][i]);
}
}
return dequantizedBlock;
}
}
```
这个代码实现了 JPEG 彩色图像压缩的过程,包括 RGB 到 YCbCr 的转换、DCT 变换、量化、反量化、IDCT 变换和 YCbCr 到 RGB 的转换。你可以将输入图像放在与代码相同的目录下,并将其命名为 `input.jpg`,然后运行代码,输出图像将保存在 `output.jpg` 中。
阅读全文