Skip to content

Commit a6e3c2e

Browse files
committed
Migrating rotation utility from core to api
1 parent 74ddf72 commit a6e3c2e

File tree

2 files changed

+149
-1
lines changed

2 files changed

+149
-1
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ plugins {
55
}
66

77
group = 'com.labelzoom.api'
8-
version = '1.0.9'
8+
version = '1.0.10'
99

1010
repositories {
1111
mavenCentral()
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package com.labelzoom.api.util;
2+
3+
/* Copyright (C) 2021, LabelZoom, a subsidiary of RJF Technology Solutions, Inc.
4+
* All rights reserved. Proprietary and confidential.
5+
*
6+
* This file is subject to the license terms found at
7+
* https://www.labelzoom.net/end-user-license-agreement/
8+
*
9+
* The methods and techniques described herein are considered
10+
* confidential and/or trade secrets.
11+
* No part of this file may be copied, modified, propagated,
12+
* or distributed except as authorized by the license.
13+
*/
14+
15+
import com.labelzoom.api.model.components.AComponent;
16+
import com.labelzoom.api.model.components.AFontComponent;
17+
import com.labelzoom.api.model.components.CLabel;
18+
import com.labelzoom.api.model.components.barcodes.linear.ALinearBarcode;
19+
20+
import java.awt.geom.AffineTransform;
21+
import java.awt.image.AffineTransformOp;
22+
import java.awt.image.BufferedImage;
23+
24+
public class RotationUtility
25+
{
26+
public static int normalizeRotation(float degrees) { return normalizeRotation(Math.round(degrees)); }
27+
28+
public static int normalizeRotation(int degrees)
29+
{
30+
degrees = degrees % 360;
31+
if (degrees < 0) degrees += 360;
32+
return degrees;
33+
}
34+
35+
public static void rotate(final CLabel label, final int degrees)
36+
{
37+
switch (degrees)
38+
{
39+
case -90:
40+
rotateCounterClockwise(label);
41+
return;
42+
case 0:
43+
return;
44+
case 90:
45+
rotateClockwise(label);
46+
break;
47+
case 180:
48+
rotateClockwise(rotateClockwise(label));
49+
break;
50+
case 270:
51+
rotateClockwise(rotateClockwise(rotateClockwise(label)));
52+
break;
53+
}
54+
}
55+
56+
private static CLabel rotateClockwise(final CLabel label)
57+
{
58+
for (AComponent component : label.getElements())
59+
{
60+
final int newX = label.getWidth() - component.getTop();
61+
final int newY = component.getLeft();
62+
component.setLeft(newX);
63+
component.setTop(newY);
64+
}
65+
66+
// TODO: Do we really want to do this?
67+
final int newWidth = label.getHeight();
68+
final int newHeight = label.getWidth();
69+
label.setWidth(newWidth);
70+
label.setHeight(newHeight);
71+
72+
if (label.getOrientation() == CLabel.PageOrientation.Portrait)
73+
{
74+
label.setOrientation(CLabel.PageOrientation.Landscape);
75+
}
76+
else if (label.getOrientation() == CLabel.PageOrientation.Landscape)
77+
{
78+
label.setOrientation(CLabel.PageOrientation.ReversePortrait);
79+
}
80+
else if (label.getOrientation() == CLabel.PageOrientation.ReversePortrait)
81+
{
82+
label.setOrientation(CLabel.PageOrientation.ReverseLandscape);
83+
}
84+
else
85+
{
86+
label.setOrientation(CLabel.PageOrientation.Portrait);
87+
}
88+
return label;
89+
}
90+
91+
/**
92+
* TODO: Counter clockwise rotation
93+
* @param label the label to rotate
94+
* @return the rotated label
95+
*/
96+
private static CLabel rotateCounterClockwise(final CLabel label)
97+
{
98+
for (AComponent component : label.getElements())
99+
{
100+
int yOffset = 0;
101+
if (component instanceof ALinearBarcode)
102+
{
103+
ALinearBarcode linearBarcode = (ALinearBarcode)component;
104+
yOffset = -linearBarcode.getHeight();
105+
}
106+
else if (component instanceof AFontComponent)
107+
{
108+
AFontComponent fontComponent = (AFontComponent)component;
109+
yOffset = -Math.round(fontComponent.getFontSize());
110+
}
111+
final int newX = component.getTop();
112+
final int newY = label.getWidth() - component.getLeft() + yOffset;
113+
component.setLeft(newX);
114+
component.setTop(newY);
115+
}
116+
117+
// TODO: Do we really want to do this?
118+
//final int newWidth = label.getHeight();
119+
//final int newHeight = label.getWidth();
120+
//label.setWidth(newWidth);
121+
//label.setHeight(newHeight);
122+
123+
return label;
124+
}
125+
126+
/**
127+
*
128+
* @param image the image to rotate
129+
* @param degrees number of degrees to rotate
130+
* @return the rotated image
131+
*/
132+
public static BufferedImage rotateImage(final BufferedImage image, int degrees)
133+
{
134+
final double rads = Math.toRadians(degrees);
135+
final double sin = Math.abs(Math.sin(rads));
136+
final double cos = Math.abs(Math.cos(rads));
137+
final int w = (int) Math.floor(image.getWidth() * cos + image.getHeight() * sin);
138+
final int h = (int) Math.floor(image.getHeight() * cos + image.getWidth() * sin);
139+
final BufferedImage rotatedImage = new BufferedImage(w, h, image.getType());
140+
final AffineTransform at = new AffineTransform();
141+
at.translate(w * 0.5d, h * 0.5d);
142+
at.rotate(rads,0, 0);
143+
at.translate(-image.getWidth() * 0.5d, -image.getHeight() * 0.5d);
144+
final AffineTransformOp rotateOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
145+
rotateOp.filter(image, rotatedImage);
146+
return rotatedImage;
147+
}
148+
}

0 commit comments

Comments
 (0)