1、图源API
在问度娘之后发现了几个可用的API,主要来自下面几个博主的分享
在线随机美图API接口服务
可以获取随机图片的API收集
随机图片API接口
最终自己测试使用的是下面三个网址:
https://uploadbeta.com/api/pictures/random //必应推荐
https://img.xjh.me/random_img.php //二次元
url返回text/html文本需要进行解析,python处理文本内容示例,获取img的src
import requests
import json
import re
def find_img_src(html):
replace_pattern = r'<[img|IMG].*?/>' #img标签的正则式
img_url_pattern = r'.+?src="(\S+)"' #img_url的正则式
replaced_img_url_list = []
img_url_list = []
need_replace_list = re.findall(replace_pattern, html)#找到所有的img标签
for tag in need_replace_list:
img_url_list.append(re.findall(img_url_pattern, tag)[0])#找到所有的img_url
return img_url_list
headers = {"User-Agent": "Mozilla/5.0"}
#"Content-Type": "text/html" ,这个返回的是text
#text中含有图片地址的src标签
# response = requests.get("https://cdn.mom1.cn/?mom=306",headers = headers)
#"Content-Type": "text/html" ,这个返回的是text
#text中含有图片地址的src标签
response = requests.get("https://img.xjh.me/random_img.php")
print(response.text)
url_list = find_img_src(response.text) #返回url列表
#"Content-Type": "image/jpeg" 或者网站直接返回的是图片
# response = requests.get("https://uploadbeta.com/api/pictures/random",headers = headers)
for i in url_list:
response = requests.get("https:"+i, headers=headers)
print(response.status_code)
if response.status_code == 200:
if (response.headers!=None):
print(json.dumps(dict(response.headers),indent=1)) #indent缩排,使得换行显示
if (response.content!=None):
# print(response.text)
open(r'C:\Users\******\Desktop\erci.png','wb').write(response.content) # 将内容写入图片
print("done")
java从文本中解析出图片的url示例,参考Java获取img标签里的src路径
public List<String>getImgSrc(String content){
List<String>list=new ArrayList<String>();
Pattern p_img=Pattern.compile("<(img|IMG)(.*?)(/>|></img>|>)");
Matcher m_img=p_img.matcher(content); //matcher方法返回对象
boolean result_img=m_img.find();
if(result_img){
while(result_img){
String str_img=m_img.group(2); //捕获组
Pattern p_src=Pattern.compile("(src|SRC)=(\"|\')(.*?)(\"|\')");
Matcher m_src=p_src.matcher(str_img);
if(m_src.find()){
String str_src=m_src.group(3);
list.add(str_src);
}
//结束匹配<img/>标签中的src
//匹配content中是否存在下一个<img/>标签,有则继续以上步骤匹配<img/>标签中的src
result_img=m_img.find();
}
}
return list;
}
https://cdn.mom1.cn/img/mom2018%20(666).jpg //妹子大图
2、JAVA获取图片
使用okhttp包,建立http连接,得到输入流,再进行解码,关于图片的解析与处理,参考Bitmap的inJustDecodeBounds属性,下面是代码示例
class Network_http_optimize {
OkHttpClient myokHttpClient = new OkHttpClient().newBuilder()
// .connectTimeout(5, TimeUnit.SECONDS) //设置连接超时
// .readTimeout(5,TimeUnit.SECONDS)
.build();
//创建get请求函数
public InputStream getInputStream(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.get()
.build();
Response response = myokHttpClient.newCall(request).execute();
return response.body().byteStream();
}
//创建get请求函数
public String getString(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.get()
.build();
Response response = myokHttpClient.newCall(request).execute();
return response.body().string();
}
}
public class Network_http extends Thread {
String im_group_url = null;
InputStream inputStream = null;
String result_json_data = null;
JSONArray data_array = null;
int category ;
Message msg = new Message();
Bitmap bitmap = null;
@Override
public void run() {
Network_http_optimize network_http_optimize = new Network_http_optimize();
category = (int)(Math.random()*10)%3;
switch(category) {
case 0:
String im_url = "https://cdn.mom1.cn/img/mom2018%20("+(int)(Math.random()*1000)+").jpg";
bitmap = Get_img_and_scale(im_url);
if (bitmap==null){System.out.println("未获取到图片->美女");}
msg.what = 1;
msg.obj = new Image_object(im_url,bitmap);
my_handler.sendMessage(msg); //每一张图片我就发送一个消息
break;
case 1:
String im_url_1 = "https://uploadbeta.com/api/pictures/random";
Bitmap bitmap = Get_img_and_scale(im_url_1);
if (bitmap==null){System.out.println("未获取到图片->必应");}
msg.what = 1;
msg.obj = new Image_object(im_url_1,bitmap);
my_handler.sendMessage(msg); //每一张图片我就发送一个消息
break;
case 2:
//这种返回的是text文本,包含img的src标签,通过正则表达式,可以获取图片正真的网络地址
String im_url_2 = "https://img.xjh.me/random_img.php"; //二次元图片API
try {
String text = network_http_optimize.getString(im_url_2);
List src_list = getImgSrc(text); //成功得到src资源
im_url_2 = "https:"+src_list.get(0).toString(); //得到真实的url
bitmap = Get_img_and_scale(im_url_2);
if (bitmap==null){System.out.println("未获取到图片->二次元");}
msg.what = 1;
msg.obj = new Image_object(im_url_2,bitmap);
my_handler.sendMessage(msg); //每一张图片我就发送一个消息
} catch (IOException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
public Bitmap Get_img_and_scale(String url) {
Network_http_optimize network_http_optimize = new Network_http_optimize();
Bitmap bitmap = null;
try {
InputStream inputStream = network_http_optimize.getInputStream(url);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
//不返回实际的bitmap,但可以通过这个bitmap获取图片的宽和高
bitmap = BitmapFactory.decodeStream(inputStream, null,options);
float realWidth = options.outWidth;
float realHeight = options.outHeight;
System.out.print("真实图片高度:" + realHeight + " 宽度:" + realWidth+" ");
int scale = (int) ((realHeight > realWidth ? realHeight : realWidth) / 1000);
if (scale <= 0) { scale = 1; }
System.out.println("缩放scale:"+scale);
inputStream.close();
options.inSampleSize = scale;
options.inJustDecodeBounds = false;
//注意这次要把options.inJustDecodeBounds 设为 false,这次图片是要读取出来的
inputStream = network_http_optimize.getInputStream(url); //重新载入,读取数据流的
bitmap = BitmapFactory.decodeStream(inputStream,null,options);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("请求出现错误");
}
return bitmap;
}
public List<String>getImgSrc(String content){
List<String>list=new ArrayList<String>();
Pattern p_img=Pattern.compile("<(img|IMG)(.*?)(/>|></img>|>)");
Matcher m_img=p_img.matcher(content); //matcher方法返回对象
boolean result_img=m_img.find();
if(result_img){
while(result_img){
String str_img=m_img.group(2);
Pattern p_src=Pattern.compile("(src|SRC)=(\"|\')(.*?)(\"|\')");
Matcher m_src=p_src.matcher(str_img);
if(m_src.find()){
String str_src=m_src.group(3);
list.add(str_src);
}
//结束匹配<img/>标签中的src
//匹配content中是否存在下一个<img/>标签,有则继续以上步骤匹配<img/>标签中的src
result_img=m_img.find();
}
}
return list;
}
}
3、显示到ListVIEW
继承adapter,建立图片对象,加载自己的布局文件,实现图片显示
public class Image_object {
String im_description;
Bitmap im_self;
int im_drawable_id;
public Image_object(String im_discription,Bitmap im_self){
this.im_description = im_discription;
this.im_self = im_self;
}
public Image_object(String im_discription,int im_drawable_id){
this.im_description = im_discription;
this.im_drawable_id = im_drawable_id;
}
public String getIm_description(){
return im_description;
}
public Bitmap getIm_self(){
return im_self;
}
public int getIm_drawable_id(){
return im_drawable_id;
}
}
public class UserListAdapter extends ArrayAdapter {
private int resourceId;
public UserListAdapter(Context context, int textViewResourceId, List objects) {
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Image_object image_object = (Image_object) getItem(position);
View view;
if(convertView==null){
view= LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
}else {view=convertView;}
TextView imagedescription = view.findViewById(R.id.image_discription);
ImageView imageself = view.findViewById(R.id.image_self);
imagedescription.setText(image_object.getIm_description());
imageself.setImageBitmap(image_object.getIm_self());
return view;
}
}
4、实现图片的点击放大与保(dialog方法)
继承dialog,添加初始化的方法,在onCreate当中设置点击与长按的监听事件,点击图片将使得dialog取消,长按将进入保存设置。方法参考点击图像显示大图Dialog,保存图片可以详细看下这篇文章Android中保存图片到本地功能实现,下面是代码示例
package com.example.pbrowser;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import androidx.annotation.NonNull;
public class Photo_zoom_dialog extends Dialog {
public Photo_zoom_dialog(@NonNull Context context) {
super(context); //需要构造方法
}
public Photo_zoom_dialog setBitmap(Bitmap bitmap){ //方法
this.bitmap = bitmap;
return this;
}
ImageView imageView;
Bitmap bitmap;
AlertDialog alertDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.z_zoom_photo);
//按空白处能取消动画
setCanceledOnTouchOutside(true);
imageView = findViewById(R.id.my_picture);
Point point = new Point();
getWindow().getWindowManager().getDefaultDisplay().getSize(point);
if (bitmap != null){
imageView.setImageBitmap(bitmap);
Window win = getWindow(); //设置显示图片区域大小
WindowManager.LayoutParams lp = win.getAttributes();
lp.gravity = Gravity.CENTER;
//如果宽度小于point.x,会按原尺寸显示,大于就屏宽显示
lp.height = WindowManager.LayoutParams.WRAP_CONTENT; //高度设置成自适应
lp.width = point.x; //这个跟手机有关系,我的HD+为720,FHD+为1080
win.setAttributes(lp);
getWindow().setBackgroundDrawableResource(android.R.color.transparent); //去点dialog的白边
}
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Photo_zoom_dialog.super.dismiss(); //调用对象自己dismiss()方法
}
});
imageView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
alertDialog = new AlertDialog.Builder(getContext())
.setMessage("保存图片")
.setPositiveButton("确定", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setNegativeButton("取消",null)
.create();
alertDialog.show();
return false;
}
});
}
}
调用就非常简单,点击ListVIEW的item,创建dialog对象,实现图片显示,代码示例
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Image_object image_object = (Image_object) display_image_list.get(position);
Photo_zoom_dialog photo_zoom_dialog = new Photo_zoom_dialog(getContext());
photo_zoom_dialog.setBitmap(image_object.getIm_self());
photo_zoom_dialog.show();
}
});