- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有原图:
我使用以下 Java 代码旋转图像:
BufferedImage bi = ImageHelper.rotateImage(bi, -imageSkewAngle);
ImageIO.write(bi, "PNG", new File("out.png"));
结果我得到了以下图像:
如何删除图像周围的黑色边界并使其成为适当的白色矩形并且不花费太多空间..仅使用所需的大小进行转换...等于原始大小或更大(如果需要)?
最佳答案
以下程序包含一个方法rotateImage
,该方法应与问题中使用的rotateImage
方法等效:它计算旋转图像的边界,创建一个具有所需尺寸的新图像,并将原始图像绘制到新图像的中心。
该方法还接收一个确定背景颜色的Color backgroundColor
。在示例中,将其设置为 Color.RED
以说明效果。
该示例还包含一个方法rotateImageInPlace
。此方法将始终创建一个与输入图像大小相同的图像,并且还会将(旋转的)原始图像绘制到该图像的中心。
该程序创建两个面板,左侧面板显示 rotateImage
的结果,右侧面板显示 rotateImageInPlace
的结果,以及一个允许更改旋转角度的 slider 。所以这个程序的输出如下所示:
(同样,Color.RED
仅用于说明。根据您的应用程序将其更改为 Color.WHITE
)
正如评论中所讨论的,不改变图像大小的目标可能并不总是可以实现,具体取决于图像的内容和旋转角度。因此,对于某些角度,旋转的图像可能不适合最终的图像。但对于问题的用例,这应该没问题:用例是原始图像已经包含旋转的矩形“感兴趣区域”。因此,输出中未出现的部分通常应该是输入图像中无论如何不包含相关信息的部分。
(否则,有必要提供有关输入图像结构、边框大小或旋转角度的更多信息,或者必须通过检查图像、像素来手动计算出所需的大小按像素,查看哪些像素是黑色的,哪些是白色的)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
public class RotateImageWithoutBorder
{
public static void main(String[] args) throws Exception
{
BufferedImage image =
ImageIO.read(new URL("/image/tMtFh.png"));
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImagePanel imagePanel0 = new ImagePanel();
imagePanel0.setBackground(Color.BLUE);
ImagePanel imagePanel1 = new ImagePanel();
imagePanel1.setBackground(Color.BLUE);
JSlider slider = new JSlider(0, 100, 1);
slider.addChangeListener(e ->
{
double alpha = slider.getValue() / 100.0;
double angleRad = alpha * Math.PI * 2;
BufferedImage rotatedImage = rotateImage(
image, angleRad, Color.RED);
imagePanel0.setImage(rotatedImage);
BufferedImage rotatedImageInPlace = rotateImageInPlace(
image, angleRad, Color.RED);
imagePanel1.setImage(rotatedImageInPlace);
f.repaint();
});
slider.setValue(0);
f.getContentPane().add(slider, BorderLayout.SOUTH);
JPanel imagePanels = new JPanel(new GridLayout(1,2));
imagePanels.add(imagePanel0);
imagePanels.add(imagePanel1);
f.getContentPane().add(imagePanels, BorderLayout.CENTER);
f.setSize(800,500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static BufferedImage rotateImage(
BufferedImage image, double angleRad, Color backgroundColor)
{
int w = image.getWidth();
int h = image.getHeight();
AffineTransform at = AffineTransform.getRotateInstance(
angleRad, w * 0.5, h * 0.5);
Rectangle rotatedBounds = at.createTransformedShape(
new Rectangle(0, 0, w, h)).getBounds();
BufferedImage result = new BufferedImage(
rotatedBounds.width, rotatedBounds.height,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.setColor(backgroundColor);
g.fillRect(0, 0, rotatedBounds.width, rotatedBounds.height);
at.preConcatenate(AffineTransform.getTranslateInstance(
-rotatedBounds.x, -rotatedBounds.y));
g.transform(at);
g.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(image, 0, 0, null);
g.dispose();
return result;
}
private static BufferedImage rotateImageInPlace(
BufferedImage image, double angleRad, Color backgroundColor)
{
int w = image.getWidth();
int h = image.getHeight();
AffineTransform at = AffineTransform.getRotateInstance(
angleRad, w * 0.5, h * 0.5);
Rectangle rotatedBounds = at.createTransformedShape(
new Rectangle(0, 0, w, h)).getBounds();
BufferedImage result = new BufferedImage(
w, h,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.setColor(backgroundColor);
g.fillRect(0, 0, w, h);
at.preConcatenate(AffineTransform.getTranslateInstance(
-rotatedBounds.x - (rotatedBounds.width - w) * 0.5,
-rotatedBounds.y - (rotatedBounds.height - h) * 0.5));
g.transform(at);
g.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(image, 0, 0, null);
g.dispose();
return result;
}
static class ImagePanel extends JPanel
{
private BufferedImage image;
public void setImage(BufferedImage image)
{
this.image = image;
repaint();
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if (image != null)
{
g.drawImage(image, 0, 0, null);
}
}
}
}
关于java - 旋转 BufferedImage 并删除黑色边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48587644/
我是 JCodec 的新手,但我正在尝试将 JCodec 图片转换为 BufferedImage。不幸的是,在 JCodec 中这样做的方法已被弃用,除了那些将图片转换为 Picture8Bit 的方
这是我的代码: byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); BufferedImag
我正在尝试使用 ImageIO 从 DICOM 文件中获取的只有 一个波段 的光栅显示图像。我不想使用 ImageIO 直接读取缓冲图像,因为我需要文件中的真实值(使用 ImageIO 直接获得的 B
我有一个名为 originalImage 的 BufferedImage,它是在 JPanel 上绘制的。我有一个名为 layer 的 BufferedImage 数组,我在 originalImag
我正在从事图像处理工作。我有一个固定大小的缓冲图像 BufferedImage targetImage = new BufferedImage(320, 240,BufferedImage.TYPE_
我在绘制 BufferedImages 时遇到问题。我正在开发基于 2D 图 block 的 map 编辑器,当我绘制图 block 时,它首先绘制较低层,然后绘制顶层。像这样: public voi
请指教。 我正在尝试将输入 BufferedImage 绘制为更大的输出 BufferedImage (带缩放)。请看一下下面的代码: public class Main { public v
我正在尝试用 Java 创建图像马赛克。我计算了我正在创建的新图像的大小,然后对于将成为马赛克一部分的每个子图像,我进行了绘制调用。 在伪代码中: create buffered image big
我在编写另一个项目时遇到了这个问题,但我已将代码简化为直接受到所述问题影响的代码。 EntryPoint.java package replaced.with.real.package.in.code
所以我尝试寻找解决方案,但找不到可以将 RGBA 格式转换为 RGB 格式的解决方案。 如果给出从 BufferedImage 到 BufferedImage 转换的简单解决方案,那将是最好的,否则问
我检查了类似名称的问题,但他们没有回答这个用例。 基本上,我是在给定坐标 (x,y) 处覆盖一些文本(文本)我在一个包中有以下函数; protected BufferedImage Process2(
我正在开发一个 Java 应用程序,在该应用程序中我正在程序上实例化一个对象的潜在大量实例,每个实例都有一个图标(BufferedImage),该图标是从一组图标中选择的(基于随机参数) 10 或 2
好吧,Stackoverflow,你是我现在的最后一行。 如果您看一下下面的代码和图片,您会发现有两个文件被立即命名 瓷砖.java TileMap.java 有关这些类(class)的更多信息,请
我正在研究图像插值,我使用双三次插值来使用AffinedTransformOp将java中图像的分辨率加倍。我使用了的BufferedImage进行放大时使用 TYPE_4BYTE_ABGR。当我尝试
我需要创建一个 AnimatedImage 类,它将采用 Image 对象数组并在给定的时间间隔内以循环方式显示它们。 这个想法是让 Swing 组件使用此 AnimatedImage 类,就像使用常
我在尝试复制 BufferedImage 对象时遇到问题。 我正在使用 drawImage (BufferedImage image, int x, int y, ImageObserver obse
我正在尝试将 Robot.createScreenCapture 函数生成的 RGB 图像转换为 ARGB 图像。我的目标是当两个图像之间的像素没有变化但我得到黑色时设置透明度。如下图所示。 例如如下
版本 1 和版本 2 有什么区别?他们似乎在我的情况下做同样的事情,但我到处都读到版本 1 是更好的方法。但是为什么? public BufferedImage getImage(Icon icon)
我对堆栈溢出进行了相当深入的研究,但到目前为止我还没有找到解决方案。 我在运行 Robolectric 测试时遇到了来自 Android Studio 的错误。 我的项目看起来是这样的: projec
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我是一名优秀的程序员,十分优秀!