You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
webcrawler/core/src/main/java/org/pqh/gif/PixivUtil.java

223 lines
8.2 KiB

package org.pqh.gif;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.FileUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.pqh.core.util.LogManger;
import org.pqh.gif.gifmaker.AnimatedGifEncoder;
import javax.imageio.ImageIO;
import javax.net.ssl.HttpsURLConnection;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static org.pqh.gif.PixivUtil.Image.big;
import static org.pqh.gif.PixivUtil.Image.small;
/**
* Created by reborn on 2017/9/24.
*/
public class PixivUtil implements LogManger{
private static final String host="http://i4.pixiv.net";
private static final String baseUrl="https://www.pixiv.net/member_illust.php?mode=medium&illust_id=";
private static final int buffer=10240;
private static final String imgPath="tmp/images/";
private static final String gifPath=imgPath+"gif/";
/**
* 合成动图
* @param illust_id
*/
public static void downLoadImg(int illust_id,String phpsessid){
InputStream is = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
ZipFile zipFile = null;
String imageUrl=baseUrl+illust_id;
String path;
try {
log.info("图片链接:"+imageUrl);
Connection.Response response=Jsoup.connect(imageUrl).cookie("PHPSESSID",phpsessid).execute();
if(response.statusCode()== HttpsURLConnection.HTTP_OK) {
Document document=response.parse();
Elements imgEle=document.select("img.original-image");
if(imgEle.size()==1){
String src=imgEle.first().attr("data-src");
downLoadImg(src);
return;
}
String script = document.select("#wrapper>script").html();
int start = script.indexOf(small.keyword);
int end = script.indexOf(big.keyword);
if (start > -1 && end > -1) {
String json = script.substring(start,end).replaceAll(".*=","");
ObjectMapper objectMapper = new ObjectMapper();
JsonNode node = objectMapper.readTree(json);
String src = node.get("src").asText().replace(small.size, big.size);
log.info("获取到图包地址:" + src);
File file=downLoadImg(src);
zipFile = new ZipFile(file);
Enumeration entrys = zipFile.entries();
log.info("开始解压");
long a = System.currentTimeMillis();
path = file.getAbsolutePath().replace(".zip", "");
while (entrys.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) entrys.nextElement();
is = zipFile.getInputStream(zipEntry);
String imgPath = path + "\\" + zipEntry.getName();
File imgFile = new File(imgPath);
FileUtils.forceMkdirParent(imgFile);
log.info("开始解压图片到:" + imgFile.getAbsolutePath());
byte buf[] = new byte[buffer];
fos = new FileOutputStream(imgFile);
bos = new BufferedOutputStream(fos, buffer);
int count;
while ((count = is.read(buf)) > -1) {
bos.write(buf, 0, count);
}
bos.close();
is.close();
ImageIO.write(ImageIO.read(imgFile),"png",new File(imgPath.replace("jpg","png")));
}
int length = new File(path).listFiles().length;
log.info(length + "张图片解压完毕,耗时:" + (System.currentTimeMillis() - a) + "ms");
if (length > 0) {
jpgToGif(document.title().split("/")[0].replaceAll("[「,」]", ""), path, node.get("frames"));
}
} else {
log.error("图包地址获取失败");
}
}else if(response.statusCode()==HttpsURLConnection.HTTP_NOT_FOUND){
log.info("图片链接:"+imageUrl+"不存在");
}else{
log.error("图片链接:"+imageUrl+"访问异常");
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(zipFile != null){
zipFile.close();
}
} catch (IOException e) {
log.error(e);
}
}
}
public static File downLoadImg(String src) throws IOException {
Connection connection = Jsoup.connect(src).header("referer", host).ignoreContentType(true);
connection.request().maxBodySize(1024 * 1024 * 1024);
Connection.Response response = connection.execute();
log.info("图片资源体积:" + response.header("content-length"));
String zipName = src.substring(src.lastIndexOf("/") + 1);
File file = new File(imgPath + zipName);
FileUtils.writeByteArrayToFile(file, response.bodyAsBytes());
log.info("图片资源下载到:" + file.getAbsolutePath());
return file;
}
/**
* jpg合成gif
* @param gifName gif文件名
* @param jpgPath jpg文件目录
*/
public static void jpgToGif(String gifName,String jpgPath,JsonNode node){
AnimatedGifEncoder animatedGifEncoder=new AnimatedGifEncoder();
OutputStream outputStream= null;
InputStream inputStream=null;
File file=new File(jpgPath);
File gifDir=new File(gifPath);
if(!gifDir.exists()){
gifDir.mkdir();
}
File gifFile=new File(gifPath+gifName+".gif");
log.info("动图将生成到"+gifFile.getAbsolutePath());
try {
gifFile.createNewFile();
outputStream = new FileOutputStream(gifFile);
animatedGifEncoder.start(outputStream);
//数组转集合
List<File> fileList= (List<File>) FileUtils.listFiles(file,new String[]{"jpg"},false);
long a=System.currentTimeMillis();
for(File f:fileList){
//获取当前帧延迟信息
int index=fileList.indexOf(f);
int delay=node.get(index).get("delay").asInt();
inputStream=new FileInputStream(f.getAbsoluteFile());
BufferedImage image = ImageIO.read(inputStream);
//把帧添加进去合成
animatedGifEncoder.addFrame(image);
animatedGifEncoder.setDelay(delay);
log.info(gifName+":正在合成第"+((index+1)+"帧"));
inputStream.close();
}
//添加完所有帧开始合成
animatedGifEncoder.finish();
long b=System.currentTimeMillis();
log.info("合成"+fileList.size()+"帧花费时间"+(b-a)+"ms");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(outputStream!=null){
outputStream.close();
}
FileUtils.deleteDirectory(file);
} catch (IOException e) {
e.printStackTrace();
}
}
if (gifFile.exists()) {
try {
Desktop.getDesktop().open(gifFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
enum Image{
small("pixiv.context.ugokuIllustData","600x600"),
big("pixiv.context.ugokuIllustFullscreenData","1920x1080");
private String keyword;
private String size;
Image(String keyword, String size) {
this.keyword = keyword;
this.size = size;
}
}
}