├── Dockerfile ├── pc └── index.php ├── mobile └── index.php ├── index.php ├── classify.py └── README.md /Dockerfile: -------------------------------------------------------------------------------- 1 | # 使用官方 PHP 镜像作为基础镜像 2 | FROM php:alpine 3 | 4 | # 将本地文件复制到容器中 5 | COPY index.php /var/www/html/ 6 | COPY pc /var/www/html/pc 7 | COPY mobile /var/www/html/mobile 8 | 9 | # 暴露容器的 80 端口 10 | EXPOSE 80 11 | 12 | # 设置容器启动时执行的命令 13 | CMD ["php", "-S", "0.0.0.0:80", "-t", "/var/www/html/"] 14 | -------------------------------------------------------------------------------- /pc/index.php: -------------------------------------------------------------------------------- 1 | 64 | -------------------------------------------------------------------------------- /mobile/index.php: -------------------------------------------------------------------------------- 1 | 64 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 73 | 74 | -------------------------------------------------------------------------------- /classify.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | import os 3 | 4 | # 检查图片方向 5 | def get_image_orientation(image_path): 6 | with Image.open(image_path) as img: 7 | width, height = img.size 8 | return "landscape" if width > height else "portrait" 9 | 10 | # 转换图片为 WebP 格式 11 | def convert_to_webp(image_path, output_folder, max_pixels=178956970): 12 | try: 13 | with Image.open(image_path) as img: 14 | # Check image size 15 | width, height = img.size 16 | if width * height > max_pixels: 17 | print(f"Skipping {image_path} because it exceeds the size limit.") 18 | return 19 | 20 | # Save the image as WebP 21 | output_path = os.path.join(output_folder, os.path.splitext(os.path.basename(image_path))[0] + ".webp") 22 | img.save(output_path, "webp") 23 | except Exception as e: 24 | print(f"Failed to convert {image_path}: {e}") 25 | 26 | # 遍历文件夹中的图片 27 | def process_images(input_folder, output_folder_landscape, output_folder_portrait): 28 | for filename in os.listdir(input_folder): 29 | if filename.endswith(('.jpg', '.jpeg', '.png')): 30 | image_path = os.path.join(input_folder, filename) 31 | orientation = get_image_orientation(image_path) 32 | try: 33 | if orientation == "landscape": 34 | convert_to_webp(image_path, output_folder_landscape) 35 | else: 36 | convert_to_webp(image_path, output_folder_portrait) 37 | except Exception as e: 38 | print(f"Error processing {image_path}: {e}. Skipping this image.") 39 | 40 | # 指定输入和输出文件夹 41 | input_folder = "/root/photos" 42 | output_folder_landscape = "/root/landscape" 43 | output_folder_portrait = "/root/portrait" 44 | 45 | # 执行转换 46 | process_images(input_folder, output_folder_landscape, output_folder_portrait) 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 搭建一个简单的随机图片API,支持Docker部署 2 | 3 | ### 更新 4 | 5 | #### 2024.5.27 6 | 7 | ##### 新增 8 | 9 | - /pc路径,显示横屏图片,例如:[https://api.neix.in/random/pc](https://api.neix.in/random/pc) 10 | 11 | ![https://api.neix.in/random/pc](https://api.neix.in/random/pc) 12 | 13 | - /mobile,显示竖屏图片,例如:[https://api.neix.in/random/mobile](https://api.neix.in/random/mobile) 14 | 15 | ![https://api.neix.in/random/mobile](https://api.neix.in/random/mobile) 16 | 17 | - 镜像大小减小了 18 | 19 | #### 简介 20 | 21 | 随机图片 API 是一种允许开发者从一个图片库或者指定的目录中获取随机图片的接口。这种 API 通常用于网站、移动应用程序或其他软件中,以便动态地展示随机图片,例如用作背景图片、占位图、或者其他需要随机化内容的场景。 22 | 23 | ### 在线体验 24 | 25 | [https://api.neix.in/random](https://api.zzii.de/random) 26 | 27 | ![https://api.neix.in/random](https://api.neix.in/random) 28 | 29 | ### 特性 30 | 31 | - 图片随机展示 32 | - 设备适配:通过检测用户代理字符串,判断访问设备是手机还是电脑,并根据设备类型选择对应的图片文件夹路径。 33 | - 图片格式支持:web,jpg,jpeg,png,gif 34 | 35 | ### 部署 36 | 37 | #### PHP 38 | 39 | 直接丢到有PHP和Nginx的环境中就行 40 | 41 | #### Docker 42 | 43 | ```yml 44 | version: '3.9' 45 | services: 46 | random-api: 47 | image: 'neixin/random-pic-api' 48 | volumes: 49 | # 竖屏图片 50 | - './portrait:/var/www/html/portrait' 51 | # 横屏图片 52 | - './landscape:/var/www/html/landscape' 53 | ports: 54 | - '8080:80' 55 | ``` 56 | 57 | ### 图片处理 58 | 59 | #### 代码 60 | 61 | ```py 62 | from PIL import Image 63 | import os 64 | 65 | # 检查图片方向 66 | def get_image_orientation(image_path): 67 | with Image.open(image_path) as img: 68 | width, height = img.size 69 | return "landscape" if width > height else "portrait" 70 | 71 | # 转换图片为 WebP 格式 72 | def convert_to_webp(image_path, output_folder, max_pixels=178956970): 73 | try: 74 | with Image.open(image_path) as img: 75 | # Check image size 76 | width, height = img.size 77 | if width * height > max_pixels: 78 | print(f"Skipping {image_path} because it exceeds the size limit.") 79 | return 80 | 81 | # Save the image as WebP 82 | output_path = os.path.join(output_folder, os.path.splitext(os.path.basename(image_path))[0] + ".webp") 83 | img.save(output_path, "webp") 84 | except Exception as e: 85 | print(f"Failed to convert {image_path}: {e}") 86 | 87 | # 遍历文件夹中的图片 88 | def process_images(input_folder, output_folder_landscape, output_folder_portrait): 89 | for filename in os.listdir(input_folder): 90 | if filename.endswith(('.jpg', '.jpeg', '.png')): 91 | image_path = os.path.join(input_folder, filename) 92 | orientation = get_image_orientation(image_path) 93 | try: 94 | if orientation == "landscape": 95 | convert_to_webp(image_path, output_folder_landscape) 96 | else: 97 | convert_to_webp(image_path, output_folder_portrait) 98 | except Exception as e: 99 | print(f"Error processing {image_path}: {e}. Skipping this image.") 100 | 101 | # 指定输入和输出文件夹 102 | input_folder = "/root/photos" 103 | output_folder_landscape = "/root/landscape" 104 | output_folder_portrait = "/root/portrait" 105 | 106 | # 执行转换 107 | process_images(input_folder, output_folder_landscape, output_folder_portrait) 108 | ``` 109 | 110 | #### 作用 111 | 112 | 将横屏和竖屏的图片分开,并转化为webp格式,使用时注意修改文件路径 113 | 114 | ### 赞助 115 | 感谢 [YXVM](https://yxvm.com/) 对本项目的支持! 116 | ### 最后 117 | 118 | 如果觉得还不错的话,可以点个star 119 | 120 | 个人博客地址:[极客与乐趣](https://blog.gckjoy.com/) 121 | 122 | 123 | ## Star History 124 | 125 | [![Star History Chart](https://api.star-history.com/svg?repos=Nei-Xin/random-pic-api&type=Date)](https://www.star-history.com/#Nei-Xin/random-pic-api&Date) 126 | 127 | --------------------------------------------------------------------------------