用java实现任意角度的图片旋转的方法 传入参数Image image(图片), float angle(旋转角度)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用java实现任意角度的图片旋转的方法 传入参数Image image(图片), float angle(旋转角度)相关的知识,希望对你有一定的参考价值。

可以加分~ 大神帮忙~

参考技术A 用js来做

java没听说过可以

不过js一定可以实现追问

就是用java代码实现。。。囧

追答

现在浏览器都支持js
干嘛就得用java来实现呢?
不好意思 用java我帮不了你

参考技术B 你是要用Graphics 画出来的image旋转还是什么旋转追问

都可以。。。我百度谷歌的方法都适合90 180 270 度的旋转
像30度 之类的 图像就不是矩形了 变成菱形
旋转30 再旋转60 跟直接旋转90的样子也不一样
还有一个方法就是 越旋转那个图片越小 虽然旋转的图片角度什么的都可以

追答

可以用

class Images
private Image image;
private double degree = 0;
private int width;
private int height;
private int x, y;
public Images(String path,int x,int y)
image = new ImageIcon(path).getImage();
this.width = image.getWidth(null);
this.height = image.getHeight(null);
this.x = x;
this.y = y;

public void rotate(double d)
if (degree > 360)
degree -= 360;

if (degree < -360)
degree += 360;

this.degree += d;

public void draw(Graphics g)
Graphics2D g2d = (Graphics2D) g;
g2d.clearRect(0, 0, WIDTH, HEIGHT);
g2d.rotate(Math.toRadians(degree), x+width/2, y+height/2);
g2d.drawImage(image, x, y, null);



rotate旋转
draw画出来

追问

  x, y 是什么啊

  现在参数只有 Image angel 这两个
  public BufferedImage imageRotate(Image image, float angle){}
能加qq 182091998或者 贴吧么 详细说说

追答

public BufferedImage rotate(Image image, float angle)
int w = image.getWidth(null);
int h = image.getHeight(null);
BufferedImage bImage = new BufferedImage(w, h,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bImage.createGraphics();
g2d.rotate(Math.toRadians(angle),w/2,h/2);
g2d.drawImage(image,0, 0, null);
g2d.dispose();
return bImage;

本回答被提问者采纳

机器视觉学习笔记最近邻插值实现图片任意角度旋转(C++)

平台:Windows 10 20H2
Visual Studio 2015
OpenCV 4.5.3


本文算法改进自图形算法与实战:6.图像运动专题(5)图像旋转-基于近邻插值的图像旋转 —— 进击的CV

原理

       将旋转后图像的像素点映射回原图像,找到它的采样点,即旋转的逆变换。映射的结果不会都是整数像素点,那么旋转后的点的像素值由与采样点最邻近的像素值表示,这就是最近邻插值。

改变尺寸的图像旋转
这种旋转是将旋转后的图像内容完全显示出来,所以要确定新的图像的尺寸。

源码

RotateImage

Mat RotateImage(Mat src, double angle)
{
	int x0, y0, x1, y1;
	angle = angle * 3.1415926535897932384626433832795 / 180;
	int dx = abs((int)src.cols*cos(angle)) + abs((int)src.rows*sin(angle));
	int dy = abs((int)src.cols*sin(angle)) + abs((int)src.rows*cos(angle));
	Mat dst(dy, dx, CV_8UC3, Scalar(0));  //创建新图像
	for (x1 = 0; x1 < dst.cols; x1++)
	{
		for (y1 = 0; y1 < dst.rows; y1++)
		{
			double fx0, fy0;
			double fx1, fy1;
			double R;
			double sita, sita0, sita1;

			//将图片中点设为坐标原点
			fx1 = x1 - dst.cols / 2;
			fy1 = y1 - dst.rows / 2;
			R = sqrt(fx1 * fx1 + fy1 * fy1);	//极径
			sita = angle;
			sita1 = atan2(fy1, fx1);			//新点极角
			sita0 = sita1 + sita;				//旧点极角
			//旧点直角坐标(中点为坐标原点)
			fx0 = R * cos(sita0);				
			fy0 = R * sin(sita0);
			//旧点直角坐标(坐标原点在角上)
			x0 = fx0 + src.cols / 2 + 0.5;
			y0 = fy0 + src.rows / 2 + 0.5;

			if (x0 >= 0 && x0 < src.cols && y0 >= 0 && y0 < src.rows)
			{
				dst.at<Vec3b>(Point(x1, y1)) = src.at<Vec3b>(Point(x0, y0));
			}
			else
				dst.at<Vec3b>(Point(x1, y1)) = 0;
		}
	}
	return dst;
}

主函数

int main(int argc, char * argv[])
{
	Mat src;

	src = imread("D:\\\\Work\\\\OpenCV\\\\Workplace\\\\Test_1\\\\4.jpg");
	imshow("原图", src);

	for (short i = -360; i <= 360; ++i)
	{
		imshow("输出", RotateImage(src, i));
		waitKey(1);
	}
	waitKey(0);

	return 0;
}

效果


完整源码

#include <opencv2\\opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

Mat RotateImage(Mat src, double angle)
{
	int x0, y0, x1, y1;
	angle = angle * 3.1415926535897932384626433832795 / 180;
	int dx = abs((int)src.cols*cos(angle)) + abs((int)src.rows*sin(angle));
	int dy = abs((int)src.cols*sin(angle)) + abs((int)src.rows*cos(angle));
	Mat dst(dy, dx, CV_8UC3, Scalar(0));  //创建新图像
	for (x1 = 0; x1 < dst.cols; x1++)
	{
		for (y1 = 0; y1 < dst.rows; y1++)
		{
			double fx0, fy0;
			double fx1, fy1;
			double R;
			double sita, sita0, sita1;

			//将图片中点设为坐标原点
			fx1 = x1 - dst.cols / 2;
			fy1 = y1 - dst.rows / 2;
			R = sqrt(fx1 * fx1 + fy1 * fy1);	//极径
			sita = angle;
			sita1 = atan2(fy1, fx1);			//新点极角
			sita0 = sita1 + sita;				//旧点极角
												//旧点直角坐标(中点为坐标原点)
			fx0 = R * cos(sita0);
			fy0 = R * sin(sita0);
			//旧点直角坐标(坐标原点在角上)
			x0 = fx0 + src.cols / 2 + 0.5;
			y0 = fy0 + src.rows / 2 + 0.5;

			if (x0 >= 0 && x0 < src.cols && y0 >= 0 && y0 < src.rows)
			{
				dst.at<Vec3b>(Point(x1, y1)) = src.at<Vec3b>(Point(x0, y0));
			}
			else
				dst.at<Vec3b>(Point(x1, y1)) = 0;
		}
	}
	return dst;
}

int main(int argc, char * argv[])
{
	Mat src;

	src = imread("D:\\\\Work\\\\OpenCV\\\\Workplace\\\\Test_1\\\\4.jpg");
	imshow("原图", src);

	for (short i = -360; i <= 360; ++i)
	{
		imshow("输出", RotateImage(src, i));
		waitKey(1);
	}
	waitKey(0);

	return 0;
}

速度优化

源码

Mat RotateImage(Mat src, float angle)
{
	int x0, y0, x1, y1;
	angle = angle * 3.1415926535897932384626433832795 / 180;
	float sin_sita = sin(angle), cos_sita = cos(angle);
	Mat dst(abs((int)src.cols*sin_sita) + abs((int)src.rows*cos_sita), abs((int)src.cols*cos_sita) + abs((int)src.rows*sin_sita), CV_8UC3, Scalar(0));  //创建新图像
	for (x1 = 0; x1 < dst.cols; ++x1)
	{
		for (y1 = 0; y1 < dst.rows; ++y1)
		{
			float fx1, fy1;

			//将图片中点设为坐标原点
			fx1 = x1 - dst.cols / 2;
			fy1 = y1 - dst.rows / 2;

			//旧点直角坐标(坐标原点在角上)
			x0 = fx1*cos_sita - fy1*sin_sita + src.cols / 2 + 0.5;
			y0 = fx1*sin_sita + fy1*cos_sita + src.rows / 2 + 0.5;

			if (x0 >= 0 && x0 < src.cols && y0 >= 0 && y0 < src.rows)
			{
				dst.at<Vec3b>(Point(x1, y1)) = src.at<Vec3b>(Point(x0, y0));
			}
			else
				dst.at<Vec3b>(Point(x1, y1)) = 0;
		}
	}
	return dst;
}

优化效果

旋转一幅1200×562的图像


用时几乎是原来的1/2

以上是关于用java实现任意角度的图片旋转的方法 传入参数Image image(图片), float angle(旋转角度)的主要内容,如果未能解决你的问题,请参考以下文章

js设置图片随机旋转角度

javascript如何实现图片任意角度的旋转?

JAVA中如何把一个Image对象旋转任意角度

vtk如何限制actor旋转角度

Winform以任意角度旋转PictureBox中的图片的方法

机器视觉学习笔记最近邻插值实现图片任意角度旋转(C++)