要实现一个能够按高度或宽度等比压缩图片并返回InputStream
的Java方法,你需要先计算图片的原始宽高比,然后根据目标尺寸(宽度或高度)计算出等比缩放后的另一个维度。以下是一个示例代码:
import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class ImageResizer {
public static InputStream resizeImage(InputStream srcInputStream, int targetWidth, int targetHeight) throws IOException {
// 读取原始图片
BufferedImage originalImage = ImageIO.read(srcInputStream);
// 计算等比缩放后的尺寸
int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
double originalWidth = originalImage.getWidth();
double originalHeight = originalImage.getHeight();
double aspectRatio = originalWidth / originalHeight;
if (targetWidth == 0) {
targetWidth = (int) (targetHeight * aspectRatio);
} else if (targetHeight == 0) {
targetHeight = (int) (targetWidth / aspectRatio);
}
// 创建一个新的BufferedImage,类型为原始图片的类型
BufferedImage resizedImage = new BufferedImage((int) targetWidth, (int) targetHeight, type);
// 使用Graphics2D来绘制缩小后的图片
Graphics2D g2d = resizedImage.createGraphics();
g2d.drawImage(originalImage, 0, 0, (int) targetWidth, (int) targetHeight, null);
g2d.dispose();
// 将缩小后的图片写入到ByteArrayOutputStream中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(resizedImage, "jpg", baos);
// 将ByteArrayOutputStream转换为InputStream
return new ByteArrayInputStream(baos.toByteArray());
}
public static void main(String[] args) {
try {
// 假设你有一个图片文件的InputStream,这里我们使用一个模拟的InputStream作为示例
// InputStream srcInputStream = new FileInputStream("path_to_your_original_image.jpg");
// 为了演示,我们使用一个空的InputStream(实际中你需要替换为真实的图片InputStream)
InputStream srcInputStream = new ByteArrayInputStream(new byte[0]); // 示例,应替换为真实图片数据
int targetWidth = 800; // 目标宽度,可以为0表示按高度缩放
int targetHeight = 600; // 目标高度,可以为0表示按宽度缩放
// 调用resizeImage方法并获取InputStream
InputStream resizedInputStream = resizeImage(srcInputStream, targetWidth, targetHeight);
// 在这里,你可以使用resizedInputStream来进一步处理图片,比如保存到文件或传输到网络等
// ...
// 关闭流(在实际应用中,确保在使用完流后关闭它们)
resizedInputStream.close();
// srcInputStream.close(); // 如果你使用了真实的文件InputStream,也请确保关闭它
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:
- 在这个示例中,
srcInputStream
是一个模拟的InputStream
,你应该替换为指向你的图片文件的真实InputStream
。 - 代码中的
targetWidth
和targetHeight
参数允许你指定目标尺寸。如果你只想按宽度缩放,可以设置targetHeight
为0;如果你只想按高度缩放,可以设置targetWidth
为0。 - 使用
ByteArrayOutputStream
和ByteArrayInputStream
可以在内存中处理图片数据,这对于不需要将图片保存到文件系统的场景很有用。 - 在处理完
InputStream
后,确保关闭它以释放资源。如果你从文件中读取InputStream
,也请确保关闭它。在上面的示例中,由于srcInputStream
是一个模拟的流,所以我没有关闭它。但在实际使用中,你应该始终关闭文件流。