You've already forked FrameTour-BE
feat(printer): 优化拼图打印偏移处理逻辑
- 添加白边框并向上偏移内容以避免打印机偏移 - 替换原有的单纯向上偏移方法 - 弃用 shiftImageUp 方法,新增 addBorderAndShiftUp 方法 - 更新临时文件命名及清理逻辑 - 修改日志记录内容以反映新的处理方式
This commit is contained in:
@@ -471,16 +471,18 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
sfpContent.setTemplateCoverUrl(template.getCoverImage());
|
sfpContent.setTemplateCoverUrl(template.getCoverImage());
|
||||||
sfpContent.setGoodsType(3);
|
sfpContent.setGoodsType(3);
|
||||||
sfpContent.setSort(0);
|
sfpContent.setSort(0);
|
||||||
IsBuyRespVO isBuyRespVO = orderBiz.isBuy(face.getScenicId(), face.getMemberId(), faceId, 5, records.getFirst().getTemplateId());
|
if (optionalRecord.isPresent()) {
|
||||||
if (isBuyRespVO.isBuy()) {
|
IsBuyRespVO isBuyRespVO = orderBiz.isBuy(face.getScenicId(), face.getMemberId(), faceId, 5, optionalRecord.get().getTemplateId());
|
||||||
sfpContent.setIsBuy(1);
|
if (isBuyRespVO.isBuy()) {
|
||||||
} else {
|
sfpContent.setIsBuy(1);
|
||||||
sfpContent.setIsBuy(0);
|
} else {
|
||||||
|
sfpContent.setIsBuy(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PriceCalculationRequest calculationRequest = new PriceCalculationRequest();
|
PriceCalculationRequest calculationRequest = new PriceCalculationRequest();
|
||||||
ProductItem productItem = new ProductItem();
|
ProductItem productItem = new ProductItem();
|
||||||
productItem.setProductType(ProductType.PHOTO_LOG);
|
productItem.setProductType(ProductType.PHOTO_LOG);
|
||||||
productItem.setProductId(records.getFirst().getTemplateId().toString());
|
productItem.setProductId(template.getId().toString());
|
||||||
productItem.setPurchaseCount(1);
|
productItem.setPurchaseCount(1);
|
||||||
productItem.setScenicId(face.getScenicId().toString());
|
productItem.setScenicId(face.getScenicId().toString());
|
||||||
calculationRequest.setProducts(Collections.singletonList(productItem));
|
calculationRequest.setProducts(Collections.singletonList(productItem));
|
||||||
|
|||||||
@@ -864,19 +864,19 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
log.error("获取景区配置失败,使用原始照片进行打印。景区ID: {}, 照片ID: {}", item.getScenicId(), item.getId(), e);
|
log.error("获取景区配置失败,使用原始照片进行打印。景区ID: {}, 照片ID: {}", item.getScenicId(), item.getId(), e);
|
||||||
}
|
}
|
||||||
} else if (item.getSourceId() != null && item.getSourceId() == 0) {
|
} else if (item.getSourceId() != null && item.getSourceId() == 0) {
|
||||||
// 拼图:向上移动40像素以避免打印机偏移
|
// 拼图:添加白边框并向上偏移以避免打印机偏移
|
||||||
try {
|
try {
|
||||||
// 生成唯一的处理标识符,避免多线程环境下的文件冲突
|
// 生成唯一的处理标识符,避免多线程环境下的文件冲突
|
||||||
String processId = item.getId() + "_" + UUID.randomUUID().toString();
|
String processId = item.getId() + "_" + UUID.randomUUID().toString();
|
||||||
File originalFile = new File("puzzle_" + processId + ".png");
|
File originalFile = new File("puzzle_" + processId + ".png");
|
||||||
File shiftedFile = new File("puzzle_" + processId + "_shifted.png");
|
File processedFile = new File("puzzle_" + processId + "_processed.png");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 下载原图
|
// 下载原图
|
||||||
HttpUtil.downloadFile(item.getCropUrl(), originalFile);
|
HttpUtil.downloadFile(item.getCropUrl(), originalFile);
|
||||||
|
|
||||||
// 向上偏移40像素
|
// 添加白边框(左右20px,上下30px)并向上偏移15px
|
||||||
ImageUtils.shiftImageUp(originalFile, shiftedFile, 40);
|
ImageUtils.addBorderAndShiftUp(originalFile, processedFile, 20, 30, 15);
|
||||||
|
|
||||||
// 上传处理后的图片
|
// 上传处理后的图片
|
||||||
IStorageAdapter adapter;
|
IStorageAdapter adapter;
|
||||||
@@ -892,21 +892,21 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
adapter = StorageFactory.use("assets-ext");
|
adapter = StorageFactory.use("assets-ext");
|
||||||
}
|
}
|
||||||
|
|
||||||
String shiftedUrl = adapter.uploadFile(null, shiftedFile, StorageConstant.PHOTO_WATERMARKED_PATH, shiftedFile.getName());
|
String processedUrl = adapter.uploadFile(null, processedFile, StorageConstant.PHOTO_WATERMARKED_PATH, processedFile.getName());
|
||||||
adapter.setAcl(StorageAcl.PUBLIC_READ, StorageConstant.PHOTO_WATERMARKED_PATH, shiftedFile.getName());
|
adapter.setAcl(StorageAcl.PUBLIC_READ, StorageConstant.PHOTO_WATERMARKED_PATH, processedFile.getName());
|
||||||
|
|
||||||
printUrl = shiftedUrl;
|
printUrl = processedUrl;
|
||||||
log.info("拼图照片向上偏移40像素成功,照片ID: {}, 新URL: {}", item.getId(), shiftedUrl);
|
log.info("拼图照片添加白边框并向上偏移成功,照片ID: {}, 新URL: {}", item.getId(), processedUrl);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("拼图照片向上偏移处理失败,使用原始照片进行打印。照片ID: {}", item.getId(), e);
|
log.error("拼图照片处理失败,使用原始照片进行打印。照片ID: {}", item.getId(), e);
|
||||||
} finally {
|
} finally {
|
||||||
// 清理临时文件
|
// 清理临时文件
|
||||||
if (originalFile != null && originalFile.exists()) {
|
if (originalFile != null && originalFile.exists()) {
|
||||||
originalFile.delete();
|
originalFile.delete();
|
||||||
}
|
}
|
||||||
if (shiftedFile != null && shiftedFile.exists()) {
|
if (processedFile != null && processedFile.exists()) {
|
||||||
shiftedFile.delete();
|
processedFile.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -448,6 +448,130 @@ public class ImageUtils {
|
|||||||
return cropped;
|
return cropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为图片添加白边框并向上偏移内容
|
||||||
|
* 用于拼图打印场景,避免打印机偏移问题
|
||||||
|
*
|
||||||
|
* @param sourceFile 源图片文件
|
||||||
|
* @param targetFile 目标图片文件
|
||||||
|
* @param horizontalBorder 左右白边框宽度(像素)
|
||||||
|
* @param verticalBorder 上下白边框高度(像素)
|
||||||
|
* @param upwardShift 内容向上偏移的像素数
|
||||||
|
* @throws IOException 读取或写入文件失败
|
||||||
|
*/
|
||||||
|
public static void addBorderAndShiftUp(File sourceFile, File targetFile,
|
||||||
|
int horizontalBorder, int verticalBorder, int upwardShift) throws IOException {
|
||||||
|
BufferedImage sourceImage = null;
|
||||||
|
BufferedImage resultImage = null;
|
||||||
|
try {
|
||||||
|
sourceImage = ImageIO.read(sourceFile);
|
||||||
|
if (sourceImage == null) {
|
||||||
|
throw new IOException("无法读取图片文件: " + sourceFile.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
int srcWidth = sourceImage.getWidth();
|
||||||
|
int srcHeight = sourceImage.getHeight();
|
||||||
|
|
||||||
|
// 计算新图片尺寸(原图 + 左右边框 + 上下边框)
|
||||||
|
int newWidth = srcWidth + horizontalBorder * 2;
|
||||||
|
int newHeight = srcHeight + verticalBorder * 2;
|
||||||
|
|
||||||
|
// 创建新图片
|
||||||
|
resultImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
|
||||||
|
Graphics2D g2d = resultImage.createGraphics();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 填充白色背景
|
||||||
|
g2d.setColor(java.awt.Color.WHITE);
|
||||||
|
g2d.fillRect(0, 0, newWidth, newHeight);
|
||||||
|
|
||||||
|
// 绘制原图到新图中
|
||||||
|
// 原图应该绘制在: x=horizontalBorder, y=verticalBorder-upwardShift 的位置
|
||||||
|
// 这样图片内容会向上偏移upwardShift像素
|
||||||
|
int drawX = horizontalBorder;
|
||||||
|
int drawY = verticalBorder - upwardShift;
|
||||||
|
|
||||||
|
g2d.drawImage(sourceImage, drawX, drawY, null);
|
||||||
|
|
||||||
|
log.info("图片添加白边框并向上偏移: 原始尺寸={}x{}, 边框=(左右{}px,上下{}px), 向上偏移={}px, 结果尺寸={}x{}",
|
||||||
|
srcWidth, srcHeight, horizontalBorder, verticalBorder, upwardShift, newWidth, newHeight);
|
||||||
|
} finally {
|
||||||
|
g2d.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存处理后的图片
|
||||||
|
ImageIO.write(resultImage, "png", targetFile);
|
||||||
|
} finally {
|
||||||
|
if (sourceImage != null) {
|
||||||
|
sourceImage.flush();
|
||||||
|
}
|
||||||
|
if (resultImage != null) {
|
||||||
|
resultImage.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向上偏移图片以避免打印机偏移问题
|
||||||
|
* 舍弃顶部指定像素,整体向上移动,并在底部补充白底
|
||||||
|
*
|
||||||
|
* @param sourceFile 源图片文件
|
||||||
|
* @param targetFile 目标图片文件
|
||||||
|
* @param offsetPixels 向上偏移的像素数(舍弃顶部的像素数,底部补充相同像素的白底)
|
||||||
|
* @throws IOException 读取或写入文件失败
|
||||||
|
* @deprecated 使用 addBorderAndShiftUp 代替
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static void shiftImageUp(File sourceFile, File targetFile, int offsetPixels) throws IOException {
|
||||||
|
BufferedImage sourceImage = null;
|
||||||
|
BufferedImage shiftedImage = null;
|
||||||
|
try {
|
||||||
|
sourceImage = ImageIO.read(sourceFile);
|
||||||
|
if (sourceImage == null) {
|
||||||
|
throw new IOException("无法读取图片文件: " + sourceFile.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = sourceImage.getWidth();
|
||||||
|
int height = sourceImage.getHeight();
|
||||||
|
|
||||||
|
if (offsetPixels <= 0 || offsetPixels >= height) {
|
||||||
|
throw new IllegalArgumentException("偏移像素必须大于0且小于图片高度,当前值: " + offsetPixels + ", 图片高度: " + height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新图片,保持原始宽度和高度
|
||||||
|
shiftedImage = new BufferedImage(width, height, sourceImage.getType());
|
||||||
|
Graphics2D g2d = shiftedImage.createGraphics();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 先填充白色背景
|
||||||
|
g2d.setColor(java.awt.Color.WHITE);
|
||||||
|
g2d.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
|
// 从源图的offsetPixels位置开始截取到底部,绘制到目标图的顶部
|
||||||
|
// 源图: 从(0, offsetPixels)到(width, height)的区域
|
||||||
|
// 目标图: 绘制到(0, 0)到(width, height-offsetPixels)的区域
|
||||||
|
g2d.drawImage(sourceImage, 0, 0, width, height - offsetPixels,
|
||||||
|
0, offsetPixels, width, height, null);
|
||||||
|
|
||||||
|
// 底部的offsetPixels像素保持白色(已通过fillRect填充)
|
||||||
|
} finally {
|
||||||
|
g2d.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存处理后的图片
|
||||||
|
ImageIO.write(shiftedImage, "png", targetFile);
|
||||||
|
log.info("图片向上偏移成功,原始尺寸: {}x{}, 偏移: {}px, 结果尺寸: {}x{} (底部补充{}px白底)",
|
||||||
|
width, height, offsetPixels, width, height, offsetPixels);
|
||||||
|
} finally {
|
||||||
|
if (sourceImage != null) {
|
||||||
|
sourceImage.flush();
|
||||||
|
}
|
||||||
|
if (shiftedImage != null) {
|
||||||
|
shiftedImage.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 裁切策略内部类
|
* 裁切策略内部类
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user