1.0-SNAPSHOT
5
.gitignore
vendored
@@ -12,3 +12,8 @@ gradle-app.setting
|
||||
|
||||
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
|
||||
# gradle/wrapper/gradle-wrapper.properties
|
||||
|
||||
.idea/
|
||||
cache
|
||||
error.log
|
||||
gradle/
|
||||
36
README.en.md
@@ -1,36 +0,0 @@
|
||||
# ink-photo-album
|
||||
|
||||
#### Description
|
||||
用Java编写的基于树莓派的电子墨水屏相册
|
||||
|
||||
#### Software Architecture
|
||||
Software architecture description
|
||||
|
||||
#### Installation
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Instructions
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### Contribution
|
||||
|
||||
1. Fork the repository
|
||||
2. Create Feat_xxx branch
|
||||
3. Commit your code
|
||||
4. Create Pull Request
|
||||
|
||||
|
||||
#### Gitee Feature
|
||||
|
||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
37
build.gradle
Normal file
@@ -0,0 +1,37 @@
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'com.github.johnrengelman.shadow' version '6.1.0'
|
||||
}
|
||||
|
||||
|
||||
group 'icu.namophice'
|
||||
version '1.0-SNAPSHOT'
|
||||
description = 'slow'
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven {
|
||||
url namophiceNexusPublic
|
||||
allowInsecureProtocol true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.76'
|
||||
// RaspbarryPi驱动接口核心包
|
||||
implementation group: 'com.pi4j', name: 'pi4j-core', version: '1.4'
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes(
|
||||
'Main-Class': 'icu.namophice.inkphotoalbum.Main'
|
||||
)
|
||||
}
|
||||
}
|
||||
4
conf.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"enable_image_fill": true, // 是否开启图片填充
|
||||
"local_images_mode": false // 本地图片库模式
|
||||
}
|
||||
BIN
images/self_1.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
images/self_10.jpg
Normal file
|
After Width: | Height: | Size: 476 KiB |
BIN
images/self_13.jpg
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
images/self_15.jpg
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
images/self_16.jpg
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
images/self_17.jpg
Normal file
|
After Width: | Height: | Size: 1012 KiB |
BIN
images/self_2.jpg
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
images/self_22.jpg
Normal file
|
After Width: | Height: | Size: 267 KiB |
BIN
images/self_6.jpg
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
2
settings.gradle
Normal file
@@ -0,0 +1,2 @@
|
||||
rootProject.name = 'ink-photo-album'
|
||||
|
||||
39
src/main/java/icu/namophice/inkphotoalbum/Main.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package icu.namophice.inkphotoalbum;
|
||||
|
||||
import icu.namophice.inkphotoalbum.business.MasterService;
|
||||
import icu.namophice.inkphotoalbum.config.DefaultConfig;
|
||||
import icu.namophice.inkphotoalbum.utils.CommonUtil;
|
||||
|
||||
/**
|
||||
* @author Namophice
|
||||
* @createTime 2021-07-29 16:42
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
public static void main(String [] args) {
|
||||
try {
|
||||
CommonUtil.printLogToConsole("Application Started ...");
|
||||
|
||||
// 初始化配置
|
||||
DefaultConfig.initConfig();
|
||||
|
||||
// 从cache文件获取imageIndex
|
||||
DefaultConfig.initImageIndexWithCache();
|
||||
|
||||
// 进入主流程
|
||||
MasterService.master();
|
||||
} catch (Exception e) {
|
||||
CommonUtil.printErrorToLogFile(e);
|
||||
} finally {
|
||||
try {
|
||||
// 打印下次获取的图片下标位置到cache文件
|
||||
CommonUtil.printImageIndexToCache(DefaultConfig.imageIndex);
|
||||
} catch (Exception e) {
|
||||
CommonUtil.printErrorToLogFile(e);
|
||||
}
|
||||
|
||||
CommonUtil.printLogToConsole("Application Exit !");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package icu.namophice.inkphotoalbum.business;
|
||||
|
||||
import icu.namophice.inkphotoalbum.config.DefaultConfig;
|
||||
import icu.namophice.inkphotoalbum.driver.EPaper;
|
||||
import icu.namophice.inkphotoalbum.utils.CommonUtil;
|
||||
import icu.namophice.inkphotoalbum.utils.ImageUtil;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author Namophice
|
||||
* @createTime 2021-08-05 10:27
|
||||
*/
|
||||
public class MasterService {
|
||||
|
||||
public static void master() throws IOException, InterruptedException {
|
||||
CommonUtil.printLogToConsole("The master program is running ...");
|
||||
|
||||
if (DefaultConfig.imageIndex < 0) {
|
||||
DefaultConfig.imageIndex = 0;
|
||||
}
|
||||
|
||||
EPaper ePaper = EPaper.getInstance();
|
||||
ePaper.init();
|
||||
|
||||
if (DefaultConfig.imageIndex == 0) {
|
||||
BufferedImage defaultImage = ImageUtil.getImageToScreen();
|
||||
|
||||
CommonUtil.printLogToConsole("Print images to screen ...");
|
||||
ePaper.drawImage(defaultImage);
|
||||
}
|
||||
|
||||
DefaultConfig.defaultImageIsLoaded = true;
|
||||
|
||||
if (DefaultConfig.local_images_mode()) { // local
|
||||
CommonUtil.printLogToConsole("Enabled local images mode ...");
|
||||
|
||||
CommonUtil.printLogToConsole("Find images directory ...");
|
||||
File imagesDir = new File(CommonUtil.rootPath + "/" + DefaultConfig.imagePath);
|
||||
|
||||
if (imagesDir.exists()) {
|
||||
if (imagesDir.isDirectory()) {
|
||||
CommonUtil.printLogToConsole("Images directory is exists ...");
|
||||
|
||||
CommonUtil.printLogToConsole("Find images files ...");
|
||||
File[] imageList = imagesDir.listFiles();
|
||||
imagesDir = null;
|
||||
|
||||
if (imageList == null || imageList.length < 1) {
|
||||
DefaultConfig.imageIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
imageList = Arrays.stream(imageList).filter(imageFile -> !imageFile.isDirectory()).toArray(File[]::new);
|
||||
if (imageList.length < 1) {
|
||||
DefaultConfig.imageIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (DefaultConfig.imageIndex < imageList.length) {
|
||||
BufferedImage targetImage = ImageUtil.getImageToScreen(imageList[DefaultConfig.imageIndex]);
|
||||
|
||||
CommonUtil.printLogToConsole("Print images to screen ...");
|
||||
ePaper.drawImage(targetImage);
|
||||
|
||||
DefaultConfig.imageIndex++;
|
||||
} else {
|
||||
DefaultConfig.imageIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // remote
|
||||
CommonUtil.printLogToConsole("Enabled remote images mode ...");
|
||||
|
||||
if (!(DefaultConfig.imageIndex < 20)) {
|
||||
DefaultConfig.imageIndex = 0;
|
||||
}
|
||||
|
||||
StringBuffer htmlStr = new StringBuffer();
|
||||
|
||||
InputStream inputStream = null;
|
||||
InputStreamReader inputStreamReader = null;
|
||||
BufferedReader bufferedReader = null;
|
||||
|
||||
try {
|
||||
URL url = new URL("https://wall.alphacoders.com/popular.php?page=" + (DefaultConfig.imageIndex + 1));
|
||||
inputStream = url.openStream();
|
||||
inputStreamReader = new InputStreamReader(inputStream, "utf-8");
|
||||
bufferedReader = new BufferedReader(inputStreamReader);
|
||||
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
htmlStr.append(line).append("\n");
|
||||
}
|
||||
|
||||
bufferedReader.close();
|
||||
} catch (IOException e) {
|
||||
DefaultConfig.imageIndex = 0;
|
||||
throw e;
|
||||
}finally {
|
||||
try {
|
||||
if(bufferedReader!=null){
|
||||
bufferedReader.close();
|
||||
bufferedReader=null;
|
||||
}
|
||||
if(inputStreamReader!=null){
|
||||
inputStreamReader.close();
|
||||
inputStreamReader=null;
|
||||
}
|
||||
if(inputStream!=null){
|
||||
inputStream.close();
|
||||
inputStream=null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (htmlStr.length() > 0) {
|
||||
final List<String> imageUrlList = new ArrayList<>();
|
||||
|
||||
final String IMGURL_REG = "(https://images(.*)thumbbig-(\\d*).jpg)";
|
||||
Matcher matcher = Pattern.compile(IMGURL_REG).matcher(htmlStr);
|
||||
while (matcher.find()){
|
||||
imageUrlList.add(matcher.group());
|
||||
}
|
||||
|
||||
if (imageUrlList.size() < 1) {
|
||||
DefaultConfig.imageIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
String imageUrl = imageUrlList.get(new Random().nextInt(imageUrlList.size()));
|
||||
imageUrl = imageUrl.replace("/thumbbig-", "/");
|
||||
|
||||
BufferedImage targetImage = ImageUtil.getImageToScreen(imageUrl, true);
|
||||
|
||||
CommonUtil.printLogToConsole("Print images to screen ...");
|
||||
ePaper.drawImage(targetImage);
|
||||
|
||||
DefaultConfig.imageIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package icu.namophice.inkphotoalbum.config;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import icu.namophice.inkphotoalbum.utils.CommonUtil;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* @author Namophice
|
||||
* @createTime 2021-08-04 11:46
|
||||
*/
|
||||
public class DefaultConfig {
|
||||
|
||||
public static final String configFileName = "conf.json";
|
||||
public static final String cacheFileName = "cache";
|
||||
|
||||
public static final String imagePath = "images";
|
||||
|
||||
public static int imageIndex;
|
||||
|
||||
/**
|
||||
* 默认图片是否被加载过
|
||||
*/
|
||||
public static boolean defaultImageIsLoaded = false;
|
||||
|
||||
/**
|
||||
* 是否开启图片填充
|
||||
*/
|
||||
private static boolean enable_image_fill = false;
|
||||
public static final boolean enable_image_fill() {
|
||||
return enable_image_fill;
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地图片库模式
|
||||
*/
|
||||
private static boolean local_images_mode = true;
|
||||
public static boolean local_images_mode() {
|
||||
return local_images_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化配置文件
|
||||
*/
|
||||
public static void initConfig() {
|
||||
CommonUtil.printLogToConsole("Init config ...");
|
||||
|
||||
File configFile = new File(CommonUtil.rootPath + "/" + configFileName);
|
||||
if (configFile.exists()) {
|
||||
|
||||
BufferedReader bufferedReader = null;
|
||||
final StringBuilder confJsonStrBuilder = new StringBuilder();
|
||||
|
||||
try {
|
||||
bufferedReader = new BufferedReader(new FileReader(configFile));
|
||||
|
||||
String lineStr;
|
||||
|
||||
while ((lineStr = bufferedReader.readLine()) != null) {
|
||||
confJsonStrBuilder.append(lineStr).append("\n");
|
||||
}
|
||||
|
||||
bufferedReader.close();
|
||||
} catch (Exception e) {
|
||||
CommonUtil.printErrorToLogFile(e);
|
||||
} finally {
|
||||
if (bufferedReader != null) {
|
||||
try {
|
||||
bufferedReader.close();
|
||||
} catch (Exception e) {
|
||||
CommonUtil.printErrorToLogFile(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final String confJsonStr = confJsonStrBuilder.toString();
|
||||
if (confJsonStr.length() > 2 && confJsonStr.contains("{") && confJsonStr.contains("}")) {
|
||||
JSONObject conJsonMap = JSONObject.parseObject(confJsonStr);
|
||||
if (conJsonMap.size() > 0) {
|
||||
if (conJsonMap.get("enable_image_fill") != null) {
|
||||
final Boolean cst_enable_image_fill = conJsonMap.getBoolean("enable_image_fill");
|
||||
if (cst_enable_image_fill != null) {
|
||||
enable_image_fill = cst_enable_image_fill;
|
||||
}
|
||||
}
|
||||
if (conJsonMap.get("local_images_mode") != null) {
|
||||
final Boolean cst_local_images_mode = conJsonMap.getBoolean("local_images_mode");
|
||||
if (cst_local_images_mode != null) {
|
||||
local_images_mode = cst_local_images_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从cache文件获取imageIndex
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void initImageIndexWithCache() throws IOException {
|
||||
CommonUtil.printLogToConsole("Init image index with cache ...");
|
||||
|
||||
DefaultConfig.imageIndex = 0;
|
||||
|
||||
File cacheFile = new File(CommonUtil.rootPath + "/" + cacheFileName);
|
||||
if (cacheFile.exists() && !cacheFile.isDirectory()) {
|
||||
BufferedReader bufferedReader = null;
|
||||
String lineStr = null;
|
||||
|
||||
try {
|
||||
bufferedReader = new BufferedReader(new FileReader(cacheFile));
|
||||
|
||||
lineStr = bufferedReader.readLine().trim();
|
||||
|
||||
bufferedReader.close();
|
||||
} catch (Exception e) {
|
||||
CommonUtil.printErrorToLogFile(e);
|
||||
} finally {
|
||||
if (bufferedReader != null) {
|
||||
try {
|
||||
bufferedReader.close();
|
||||
} catch (Exception e) {
|
||||
CommonUtil.printErrorToLogFile(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lineStr.length() > 0) {
|
||||
DefaultConfig.imageIndex = Integer.parseInt(lineStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
342
src/main/java/icu/namophice/inkphotoalbum/driver/EPaper.java
Normal file
@@ -0,0 +1,342 @@
|
||||
package icu.namophice.inkphotoalbum.driver;
|
||||
|
||||
import com.pi4j.io.gpio.*;
|
||||
import com.pi4j.io.spi.SpiChannel;
|
||||
import com.pi4j.io.spi.SpiDevice;
|
||||
import com.pi4j.io.spi.SpiFactory;
|
||||
import icu.namophice.inkphotoalbum.utils.CommonUtil;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Namophice
|
||||
* @createTime 2021-07-29 17:00
|
||||
*/
|
||||
public class EPaper {
|
||||
|
||||
public static final int width = 800;
|
||||
public static final int height = 480;
|
||||
public static final long resolution = width * height;
|
||||
|
||||
private EPaper() {}
|
||||
|
||||
private static EPaper ePaper;
|
||||
|
||||
public static EPaper getInstance() {
|
||||
return ePaper = new EPaper();
|
||||
}
|
||||
|
||||
private static GpioPinDigitalOutput CS;
|
||||
private static GpioPinDigitalOutput DC;
|
||||
private static GpioPinDigitalOutput RST;
|
||||
private static GpioPinDigitalInput BUSY;
|
||||
|
||||
public static SpiDevice spiDevice;
|
||||
|
||||
static {
|
||||
RaspiGpioProvider raspiGpioProvider = new RaspiGpioProvider(RaspiPinNumberingScheme.BROADCOM_PIN_NUMBERING);
|
||||
|
||||
final GpioController gpio = GpioFactory.getInstance();
|
||||
|
||||
CS = gpio.provisionDigitalOutputPin(raspiGpioProvider, RaspiBcmPin.GPIO_08, "CS", PinState.HIGH);
|
||||
DC = gpio.provisionDigitalOutputPin(raspiGpioProvider, RaspiBcmPin.GPIO_25, "DC", PinState.HIGH);
|
||||
RST = gpio.provisionDigitalOutputPin(raspiGpioProvider, RaspiBcmPin.GPIO_17, "RST", PinState.HIGH);
|
||||
BUSY = gpio.provisionDigitalInputPin(raspiGpioProvider, RaspiBcmPin.GPIO_24, "BUSY");
|
||||
|
||||
try {
|
||||
spiDevice = SpiFactory.getInstance(SpiChannel.CS1, SpiDevice.DEFAULT_SPI_SPEED, SpiDevice.DEFAULT_SPI_MODE);
|
||||
} catch (Exception e) {
|
||||
CommonUtil.printErrorToLogFile(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制图片到屏幕
|
||||
* @param image
|
||||
* @throws IOException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void drawImage(BufferedImage image) throws IOException, InterruptedException {
|
||||
this.initLut();
|
||||
this.clear();
|
||||
this.display(image);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置屏幕
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void reset() throws InterruptedException {
|
||||
CommonUtil.printLogToConsole("Reset the screen ...");
|
||||
|
||||
RST.high();
|
||||
Thread.sleep(200);
|
||||
RST.low();
|
||||
Thread.sleep(10);
|
||||
RST.high();
|
||||
Thread.sleep(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入指令
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public void sendCommand(int data) throws IOException {
|
||||
DC.low();
|
||||
CS.low();
|
||||
spiDevice.write((byte) data);
|
||||
CS.high();
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入数据
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public void sendData(int data) throws IOException {
|
||||
DC.high();
|
||||
CS.low();
|
||||
spiDevice.write((byte) data);
|
||||
CS.high();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查屏幕是否Busy
|
||||
* @throws IOException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void checkBusy() throws IOException, InterruptedException {
|
||||
CommonUtil.printLogToConsole("Check whether the screen is busy ...");
|
||||
|
||||
this.sendCommand((byte) 0x71);
|
||||
while (BUSY.isLow()) {
|
||||
this.sendCommand((byte) 0x71);
|
||||
Thread.sleep(200);
|
||||
}
|
||||
}
|
||||
|
||||
public void init() throws IOException, InterruptedException {
|
||||
CommonUtil.printLogToConsole("Init the driver ...");
|
||||
|
||||
reset();
|
||||
|
||||
this.sendCommand(0x01); // power setting
|
||||
this.sendData(0x17); // 1-0=11: internal power
|
||||
this.sendData(Voltage_Frame_7IN5_V2[6]); // VGH&VGL
|
||||
this.sendData(Voltage_Frame_7IN5_V2[1]); // VSH
|
||||
this.sendData(Voltage_Frame_7IN5_V2[2]); // VSL
|
||||
this.sendData(Voltage_Frame_7IN5_V2[3]); // VSHR
|
||||
|
||||
this.sendCommand(0x82); // # VCOM DC Setting
|
||||
this.sendData(Voltage_Frame_7IN5_V2[4]); // VCOM
|
||||
|
||||
this.sendCommand(0x06); // Booster Setting
|
||||
this.sendData(0x27);
|
||||
this.sendData(0x27);
|
||||
this.sendData(0x2F);
|
||||
this.sendData(0x17);
|
||||
|
||||
this.sendCommand(0x30); // OSC Setting
|
||||
this.sendData(Voltage_Frame_7IN5_V2[0]); // 2-0=100: N=4 5-3=111: M=7 3C=50Hz 3A=100HZ
|
||||
|
||||
this.sendCommand(0x04); // power on
|
||||
this.checkBusy();
|
||||
|
||||
this.sendCommand(0X00); // PANNEL SETTING
|
||||
this.sendData(0x3F); // #KW-3f KWR-2F BWROTP 0f BWOTP 1f
|
||||
|
||||
this.sendCommand(0x61); // tres
|
||||
this.sendData(0x03); // source 800
|
||||
this.sendData(0x20);
|
||||
this.sendData(0x01); // gate 480
|
||||
this.sendData(0xE0);
|
||||
|
||||
this.sendCommand(0X15);
|
||||
this.sendData(0x00);
|
||||
|
||||
this.sendCommand(0X50); // VCOM AND DATA INTERVAL SETTING
|
||||
this.sendData(0x10);
|
||||
this.sendData(0x07);
|
||||
|
||||
this.sendCommand(0X60); // TCON SETTING
|
||||
this.sendData(0x22);
|
||||
|
||||
this.sendCommand(0x65); // Resolution setting
|
||||
this.sendData(0x00);
|
||||
this.sendData(0x00); // 800*480
|
||||
this.sendData(0x00);
|
||||
this.sendData(0x00);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化LUT
|
||||
* @throws IOException
|
||||
*/
|
||||
public void initLut() throws IOException {
|
||||
CommonUtil.printLogToConsole("Set LUT ...");
|
||||
|
||||
this.sendCommand(0x20);
|
||||
for (int data : LUT_VCOM_7IN5_V2) {
|
||||
this.sendData(data);
|
||||
}
|
||||
|
||||
this.sendCommand(0x21);
|
||||
for (int data : LUT_WW_7IN5_V2) {
|
||||
this.sendData(data);
|
||||
}
|
||||
|
||||
this.sendCommand(0x22);
|
||||
for (int data : LUT_BW_7IN5_V2) {
|
||||
this.sendData(data);
|
||||
}
|
||||
|
||||
this.sendCommand(0x23);
|
||||
for (int data : LUT_WB_7IN5_V2) {
|
||||
this.sendData(data);
|
||||
}
|
||||
|
||||
this.sendCommand(0x24);
|
||||
for (int data : LUT_BB_7IN5_V2) {
|
||||
this.sendData(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清屏
|
||||
* @throws IOException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void clear() throws IOException, InterruptedException {
|
||||
CommonUtil.printLogToConsole("Clear screen ...");
|
||||
|
||||
this.initLut();
|
||||
|
||||
this.sendCommand(0x10);
|
||||
|
||||
for (int i = 0; i < resolution; i++) {
|
||||
this.sendData(0xFF);
|
||||
}
|
||||
|
||||
this.sendCommand(0x13);
|
||||
|
||||
for (int i = 0; i < resolution; i++) {
|
||||
this.sendData(0xFF);
|
||||
}
|
||||
|
||||
this.sendCommand(0x12);
|
||||
|
||||
this.checkBusy();
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制屏幕画面
|
||||
* @param image
|
||||
* @throws IOException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void display(BufferedImage image) throws IOException, InterruptedException {
|
||||
final byte[] pixels = ((DataBufferByte)(image.getRaster().getDataBuffer())).getData();
|
||||
this.display(pixels);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制屏幕画面
|
||||
* @param pixels
|
||||
* @throws IOException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void display(byte[] pixels) throws IOException, InterruptedException {
|
||||
CommonUtil.printLogToConsole("Print image to screen ...");
|
||||
|
||||
this.initLut();
|
||||
|
||||
this.sendCommand(0x13);
|
||||
|
||||
int step = 0;
|
||||
int temp = 0;
|
||||
|
||||
for (int i = 0; i < 800 * 480; i++) {
|
||||
int grayNum = pixels[i] & 0xFF;
|
||||
if (grayNum < GRAY_SCALE_OF_4[0]) {
|
||||
temp |= 1;
|
||||
} else if(grayNum < GRAY_SCALE_OF_4[1]){
|
||||
temp |= 0;
|
||||
}else if (grayNum < GRAY_SCALE_OF_4[2]) {
|
||||
temp |= 1;
|
||||
} else if(grayNum <= GRAY_SCALE_OF_4[3]){
|
||||
temp |= 0;
|
||||
}
|
||||
|
||||
step++;
|
||||
if (step != 8) {
|
||||
temp = temp << 1;
|
||||
} else {
|
||||
step = 0;
|
||||
this.sendData(temp);
|
||||
temp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
this.sendCommand(0x12);
|
||||
|
||||
this.checkBusy();
|
||||
}
|
||||
|
||||
private final static int[] Voltage_Frame_7IN5_V2 = { 0x6, 0x3F, 0x3F, 0x11, 0x24, 0x7, 0x17 };
|
||||
|
||||
private static final int[] GRAY_SCALE_OF_4 = {0xff / 4, 0xff / 4 * 2, 0xff / 4 * 3, 0xff};
|
||||
|
||||
private final static int[] LUT_VCOM_7IN5_V2 = {
|
||||
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
|
||||
0x0, 0xF, 0x1, 0xF, 0x1, 0x2,
|
||||
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||
};
|
||||
|
||||
private final static int[] LUT_WW_7IN5_V2 = {
|
||||
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
|
||||
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
|
||||
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||
};
|
||||
|
||||
private final static int[] LUT_BW_7IN5_V2 = {
|
||||
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
|
||||
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
|
||||
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||
};
|
||||
|
||||
private final static int[] LUT_WB_7IN5_V2 = {
|
||||
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
|
||||
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
|
||||
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||
};
|
||||
|
||||
private final static int[] LUT_BB_7IN5_V2 = {
|
||||
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
|
||||
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
|
||||
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package icu.namophice.inkphotoalbum.utils;
|
||||
|
||||
import icu.namophice.inkphotoalbum.config.DefaultConfig;
|
||||
|
||||
import java.io.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* @author Namophice
|
||||
* @createTime 2021-08-01 17:44
|
||||
*/
|
||||
public class CommonUtil {
|
||||
|
||||
/**
|
||||
* 获取程序运行根目录
|
||||
* @return
|
||||
*/
|
||||
public static String rootPath = System.getProperty("user.dir");
|
||||
|
||||
/**
|
||||
* 打印异常信息至error.log
|
||||
* @param exception
|
||||
*/
|
||||
public static void printErrorToLogFile(Exception exception) {
|
||||
printErrorToLogFile(exception, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印异常信息至error.log
|
||||
* @param exception
|
||||
* @param clearLogFile
|
||||
*/
|
||||
public static void printErrorToLogFile(Exception exception, boolean clearLogFile) {
|
||||
if (exception != null) {
|
||||
try {
|
||||
exception.printStackTrace();
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
|
||||
exception.printStackTrace(pw);
|
||||
final String errorDetail = "Error [" + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:ms").format(LocalDateTime.now()) + "] " + sw;
|
||||
|
||||
sw.close();
|
||||
pw.close();
|
||||
|
||||
File logFile = new File(rootPath + "/error.log");
|
||||
if ((!logFile.exists()) || logFile.isDirectory()) {
|
||||
logFile.createNewFile();
|
||||
}
|
||||
|
||||
FileWriter fileWriter = new FileWriter(logFile, clearLogFile);
|
||||
fileWriter.write(errorDetail);
|
||||
fileWriter.flush();
|
||||
fileWriter.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日志时间头
|
||||
* @return
|
||||
*/
|
||||
public static String getLogTime() {
|
||||
return "[" + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:ms").format(LocalDateTime.now()) + "] ";
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印日志到控制台
|
||||
* @param log
|
||||
*/
|
||||
public static void printLogToConsole(final String log) {
|
||||
System.out.println("Info " + getLogTime() + log);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印图片下标位置到cache文件
|
||||
* @param imageIndex
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void printImageIndexToCache(int imageIndex) throws IOException {
|
||||
CommonUtil.printLogToConsole("Print image index to cache file ...");
|
||||
|
||||
File cacheFile = new File(CommonUtil.rootPath + "/" + DefaultConfig.cacheFileName);
|
||||
if ((!cacheFile.exists()) || cacheFile.isDirectory()) {
|
||||
cacheFile.createNewFile();
|
||||
}
|
||||
FileWriter fileWriter = new FileWriter(cacheFile, false);
|
||||
fileWriter.write(String.valueOf(imageIndex));
|
||||
fileWriter.flush();
|
||||
fileWriter.close();
|
||||
}
|
||||
|
||||
}
|
||||
344
src/main/java/icu/namophice/inkphotoalbum/utils/ImageUtil.java
Normal file
@@ -0,0 +1,344 @@
|
||||
package icu.namophice.inkphotoalbum.utils;
|
||||
|
||||
import icu.namophice.inkphotoalbum.config.DefaultConfig;
|
||||
import icu.namophice.inkphotoalbum.driver.EPaper;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.URL;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Namophice
|
||||
* @createTime 2021-08-04 16:28
|
||||
*/
|
||||
public class ImageUtil {
|
||||
|
||||
/**
|
||||
* 获取可直接打印至屏幕的Image流
|
||||
* @param imagePath
|
||||
* @param isRemoteUrl
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static BufferedImage getImageToScreen(final String imagePath, final boolean isRemoteUrl) throws IOException {
|
||||
BufferedImage targetImage = getImage(imagePath, isRemoteUrl);
|
||||
targetImage = tailoringImage(targetImage, EPaper.width, EPaper.height, DefaultConfig.enable_image_fill());
|
||||
targetImage = getGaryImg(targetImage);
|
||||
|
||||
return targetImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可直接打印至屏幕的Image流
|
||||
* @param imageFile
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static BufferedImage getImageToScreen(File imageFile) throws IOException {
|
||||
BufferedImage targetImage = getImage(imageFile);
|
||||
targetImage = tailoringImage(targetImage, EPaper.width, EPaper.height, DefaultConfig.enable_image_fill());
|
||||
targetImage = getGaryImg(targetImage);
|
||||
|
||||
return targetImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可直接打印至屏幕的Image流
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static BufferedImage getImageToScreen() throws IOException {
|
||||
return getImageToScreen(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图片流
|
||||
* @param imageUrl
|
||||
* @param isRemoteUrl
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static BufferedImage getImage(final String imageUrl, final boolean isRemoteUrl) throws IOException {
|
||||
CommonUtil.printLogToConsole("Input image to BufferedImage ...");
|
||||
|
||||
if (imageUrl == null || imageUrl.length() < 1) {
|
||||
return getDefaultImage();
|
||||
} else {
|
||||
InputStream imageStream;
|
||||
|
||||
if (isRemoteUrl) {
|
||||
CommonUtil.printLogToConsole("Image path: " + imageUrl + " ...");
|
||||
|
||||
URL url = new URL(imageUrl);
|
||||
imageStream = url.openStream();
|
||||
} else {
|
||||
File imgFile = new File(imageUrl);
|
||||
if (imgFile.exists()) {
|
||||
CommonUtil.printLogToConsole("Image path: " + imgFile.getAbsolutePath() + " ...");
|
||||
|
||||
imageStream = new FileInputStream(imgFile);
|
||||
} else {
|
||||
return getDefaultImage();
|
||||
}
|
||||
}
|
||||
|
||||
BufferedImage originImage = ImageIO.read(imageStream);
|
||||
imageStream.close();
|
||||
imageStream = null;
|
||||
|
||||
BufferedImage targetImage = new BufferedImage(originImage.getWidth(), originImage.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
|
||||
for (int i = 0; i < originImage.getWidth(); i++) {
|
||||
for (int j = 0; j < originImage.getHeight(); j++) {
|
||||
targetImage.setRGB(i, j, originImage.getRGB(i, j));
|
||||
}
|
||||
}
|
||||
|
||||
return targetImage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图片流
|
||||
* @param imageFile
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static BufferedImage getImage(File imageFile) throws IOException {
|
||||
CommonUtil.printLogToConsole("Input image to BufferedImage ...");
|
||||
|
||||
if (imageFile == null || !imageFile.exists() || imageFile.isDirectory()) {
|
||||
return getDefaultImage();
|
||||
} else {
|
||||
CommonUtil.printLogToConsole("Image path: " + imageFile.getAbsolutePath() + " ...");
|
||||
|
||||
InputStream imageStream = new FileInputStream(imageFile);
|
||||
BufferedImage originImage = ImageIO.read(imageStream);
|
||||
imageStream.close();
|
||||
|
||||
BufferedImage targetImage = new BufferedImage(originImage.getWidth(), originImage.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
|
||||
for (int i = 0; i < originImage.getWidth(); i++) {
|
||||
for (int j = 0; j < originImage.getHeight(); j++) {
|
||||
targetImage.setRGB(i, j, originImage.getRGB(i, j));
|
||||
}
|
||||
}
|
||||
|
||||
return targetImage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认图片流
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static BufferedImage getDefaultImage() throws IOException {
|
||||
CommonUtil.printLogToConsole("Input default image to BufferedImage ...");
|
||||
|
||||
InputStream defaultImageStream = CommonUtil.class.getClassLoader().getResourceAsStream("images/default.bmp");
|
||||
BufferedImage originImage = ImageIO.read(defaultImageStream);
|
||||
defaultImageStream.close();
|
||||
defaultImageStream = null;
|
||||
|
||||
BufferedImage targetImage = new BufferedImage(originImage.getWidth(), originImage.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
|
||||
for (int i = 0; i < originImage.getWidth(); i++) {
|
||||
for (int j = 0; j < originImage.getHeight(); j++) {
|
||||
targetImage.setRGB(i, j, originImage.getRGB(i, j));
|
||||
}
|
||||
}
|
||||
|
||||
return targetImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对图片做自适应or填充处理(默认自适应)
|
||||
* @param originImage
|
||||
* @param screenWidth
|
||||
* @param screenHeight
|
||||
* @param enable_image_fill
|
||||
* @return
|
||||
*/
|
||||
public static BufferedImage tailoringImage(BufferedImage originImage, final int screenWidth, final int screenHeight, final boolean enable_image_fill) {
|
||||
CommonUtil.printLogToConsole("Tailoring image with screen ...");
|
||||
|
||||
// 获取原始图片宽高
|
||||
final BigDecimal originWidth = new BigDecimal(originImage.getWidth());
|
||||
final BigDecimal originHeight = new BigDecimal(originImage.getHeight());
|
||||
|
||||
BufferedImage targetImage;
|
||||
|
||||
if (originWidth.intValue() == screenWidth && originHeight.intValue() == screenHeight) { // 图片宽高 == 屏幕宽高
|
||||
return originImage;
|
||||
} else if (originWidth.intValue() < screenWidth && originHeight.intValue() < screenHeight) { // 图片宽高 皆小于 屏幕宽高
|
||||
targetImage = new BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
// 将原图居中,计算原图在输出图片中的位置
|
||||
final int xStart = (screenWidth - originWidth.intValue()) / 2;
|
||||
final int xEnd = originWidth.intValue() + xStart;
|
||||
final int yStart = (screenHeight - originHeight.intValue()) / 2;
|
||||
final int yEnd = originHeight.intValue() + yStart;
|
||||
|
||||
for (int x = 0; x < screenWidth; x++) {
|
||||
for (int y = 0; y < screenHeight; y++) {
|
||||
// 在输出图片中未被原始图片覆盖的位置直接做涂黑处理
|
||||
if (x < xStart || x >= xEnd) {
|
||||
targetImage.setRGB(x, y, 0);
|
||||
} else {
|
||||
if (y < yStart || y >= yEnd) {
|
||||
targetImage.setRGB(x, y, 0);
|
||||
} else {
|
||||
targetImage.setRGB(x, y, originImage.getRGB(x - xStart, y - yStart));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return targetImage;
|
||||
} else { // 图片宽 > 屏幕宽 or 图片高 > 屏幕高
|
||||
// 屏幕宽高比例
|
||||
final BigDecimal screenPercentage = new BigDecimal(screenWidth).divide(new BigDecimal(screenHeight), 5, RoundingMode.HALF_DOWN);
|
||||
// 原图宽高比例
|
||||
final BigDecimal imagePercentage = originWidth.divide(originHeight, 5, RoundingMode.HALF_UP);
|
||||
|
||||
|
||||
int percentageCompareRes = screenPercentage.compareTo(imagePercentage);
|
||||
if (percentageCompareRes == 0) { // 图片宽高比例 == 屏幕宽高比例
|
||||
return originImage;
|
||||
} else {
|
||||
// 等比例放大,相同高度下,屏幕宽度小于原图宽度
|
||||
boolean check = originHeight.multiply(new BigDecimal(screenWidth)).compareTo(originWidth.multiply(new BigDecimal(screenHeight))) < 1;
|
||||
|
||||
if (!DefaultConfig.defaultImageIsLoaded || !enable_image_fill) { // 自适应模式
|
||||
CommonUtil.printLogToConsole("Enabled image adaptive mode ...");
|
||||
|
||||
if (check) {
|
||||
final int targetWight = originWidth.intValue();
|
||||
final int targetHeight = originWidth.divide(screenPercentage, 0, RoundingMode.HALF_DOWN).intValue();
|
||||
|
||||
targetImage = new BufferedImage(targetWight, targetHeight, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
final int yStart = (targetHeight - originHeight.intValue()) / 2;
|
||||
final int yEnd = originHeight.intValue() + yStart;
|
||||
|
||||
for (int x = 0; x < targetWight; x++) {
|
||||
for (int y = 0; y < targetHeight; y++) {
|
||||
if (yStart <= y && y < yEnd) {
|
||||
targetImage.setRGB(x, y, originImage.getRGB(x, y - yStart));
|
||||
} else {
|
||||
targetImage.setRGB(x, y, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final int targetWight = originHeight.multiply(screenPercentage).intValue();
|
||||
final int targetHeight = originHeight.intValue();
|
||||
|
||||
targetImage = new BufferedImage(targetWight, targetHeight, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
final int xStart = (targetWight - originWidth.intValue()) / 2;
|
||||
final int xEnd = originWidth.intValue() + xStart;
|
||||
|
||||
for (int x = 0; x < targetWight; x++) {
|
||||
for (int y = 0; y < targetHeight; y++) {
|
||||
if (xStart <= x && x < xEnd) {
|
||||
targetImage.setRGB(x, y, originImage.getRGB(x - xStart, y));
|
||||
} else {
|
||||
targetImage.setRGB(x, y, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // 填充模式
|
||||
CommonUtil.printLogToConsole("Enabled image fill mode ...");
|
||||
|
||||
if (check) {
|
||||
final int targetWight = originHeight.multiply(screenPercentage).intValue();
|
||||
final int targetHeight = originHeight.intValue();
|
||||
|
||||
targetImage = new BufferedImage(targetWight, targetHeight, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
final int xStart = originWidth.subtract(new BigDecimal(targetWight)).divide(new BigDecimal(2), 0, RoundingMode.HALF_UP).intValue();
|
||||
final int xEnd = originWidth.intValue() - xStart;
|
||||
|
||||
for (int x = 0; x < originWidth.intValue(); x++) {
|
||||
for (int y = 0; y < originHeight.intValue(); y++) {
|
||||
if (xStart <= x && x < xEnd) {
|
||||
targetImage.setRGB(x - xStart, y, originImage.getRGB(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final int targetWight = originWidth.intValue();
|
||||
final int targetHeight = originWidth.divide(screenPercentage, 0, RoundingMode.HALF_UP).intValue();
|
||||
|
||||
targetImage = new BufferedImage(targetWight, targetHeight, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
final int yStart = originHeight.subtract(new BigDecimal(targetHeight)).divide(new BigDecimal(2), 0, RoundingMode.HALF_UP).intValue();
|
||||
final int yEnd = originHeight.intValue() - yStart;
|
||||
|
||||
for (int x = 0; x < originWidth.intValue(); x++) {
|
||||
for (int y = 0; y < originHeight.intValue(); y++) {
|
||||
if (yStart <= y && y < yEnd) {
|
||||
targetImage.setRGB(x, y - yStart, originImage.getRGB(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据屏幕做等比例缩放
|
||||
CommonUtil.printLogToConsole("Scale image to the screen ...");
|
||||
BufferedImage finallyImage = new BufferedImage(EPaper.width, EPaper.height, BufferedImage.TYPE_BYTE_GRAY);
|
||||
Graphics graphics = finallyImage.getGraphics();
|
||||
graphics.drawImage(targetImage, 0, 0, EPaper.width, EPaper.height, null);
|
||||
|
||||
return finallyImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取灰度图
|
||||
* @param originImage
|
||||
* @return
|
||||
*/
|
||||
public static BufferedImage getGaryImg(BufferedImage originImage) {
|
||||
CommonUtil.printLogToConsole("Convert RGB to GRAY ...");
|
||||
|
||||
// 获取原始图片宽高
|
||||
final int width = originImage.getWidth();
|
||||
final int height = originImage.getHeight();
|
||||
|
||||
BufferedImage targetImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
int rgb = originImage.getRGB(i, j);
|
||||
int oneGate = rgb & 0xffffff;
|
||||
int randomNum = new Random().nextInt(0xffffff);
|
||||
int binValue;
|
||||
|
||||
//0是黑 1是白 ,或者说数值小就靠近黑色,数值大就靠近白色
|
||||
if(oneGate > 0xec82e0) { // 大于一定数值,直接用白点
|
||||
binValue = 0xffffff;
|
||||
} else if(oneGate < 0x6ea050) { // 小于一定数值直接用黑点
|
||||
binValue = 0;
|
||||
} else if(oneGate > randomNum) { // 模拟灰阶使用随机数画白点
|
||||
binValue = 0xffffff;
|
||||
} else {
|
||||
binValue = 0;
|
||||
}
|
||||
targetImage.setRGB(i, j, binValue);
|
||||
}
|
||||
}
|
||||
|
||||
return targetImage;
|
||||
}
|
||||
|
||||
}
|
||||
BIN
src/main/resources/images/default.bmp
Normal file
|
After Width: | Height: | Size: 47 KiB |
33
src/test/java/icu/namophice/inkphotoalbum/Test.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package icu.namophice.inkphotoalbum;
|
||||
|
||||
import icu.namophice.inkphotoalbum.config.DefaultConfig;
|
||||
import icu.namophice.inkphotoalbum.utils.CommonUtil;
|
||||
import icu.namophice.inkphotoalbum.utils.ImageUtil;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Namophice
|
||||
* @createTime 2021-07-29 16:43
|
||||
*/
|
||||
public class Test {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
BufferedImage targetImage = ImageUtil.getImageToScreen(CommonUtil.rootPath + "/" + DefaultConfig.imagePath + "/" + "self_22.jpg", false);
|
||||
printImage(targetImage, CommonUtil.rootPath + "/test.jpg");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
CommonUtil.printErrorToLogFile(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void printImage(BufferedImage image, String path) throws IOException {
|
||||
File file = new File(path);
|
||||
ImageIO.write(image, "JPG", file);
|
||||
}
|
||||
|
||||
}
|
||||