一个简单的随机图API实现

实现代码

<?php

$user_config = [
    "output" => "cdn", // cdn or pass
    "cdn_choose" => "miui",
    "default_album" => "yuri",
    "mobile_default_album" => "kano_vertical",
    "diff_domain" => "false", // true or false
    "referer_list" => [
        "kanochan.net",
        "newtable.kanochan.net"
    ]
];

$cdn_list = [
    "local" => "https://api-images.kanochan.net/library",
    "miui" => "https://cdn.miui.ink/img/api-100",
    "cloudflare" => "https://p.kksk.ltd/library",
    "hellonewworld" => "https://api.hellonewworld.net/iro/KanoChan/library", 
    "ilulu" => "https://cdn.ilulu.ink/img/api-100", 
    "laiyun" => "https://contents.kanochan.net/api-img/library"
];

$image_info = [
    "Genshin-Impact" => [
        "CDN_dir" => "/genshin-impact/",
        "local_dir" => "./library/genshin-impact/",
        "image_list" => ["91247220_p0.webp","88477282_p0.webp","96821803_p0.webp","97555581_p0.webp","95828445_p0.webp","91988144_p0.webp","97313182_p0.webp","100249400_p0.webp","84666651_p0.webp","93077129_p0.webp","93015888_p0.webp","101595682_p0.webp","96542642_p0.webp","93239045_p0.webp","90904448_p0.webp","80172617_p0.webp","92564859_p0.webp","101664845_p0.webp","102169815_p0.webp","89219826_p0.webp","97833640_p0.webp","85339379_p0.webp","85467403_p0.webp","95579662_p0.webp","101414698_p0.webp","84938851_p0.webp","95605647_p0.webp","84808425_p0.webp","91623339_p0.webp","90549488_p0.webp","91364618_p0.webp","92161881_p0.webp","93077711_p0.webp","93113675_p0.webp","95028648_p0.webp","101893893_p0.webp","85984123_p0.webp","95916021_p0.webp","90285518_p0.webp","93604793_p0.webp","89419792_p0.webp","96539574_p0.webp","89490341_p0.webp","95789722_p0.webp","90640803_p0.webp","93200241_p0.webp","102113894_p0.webp","96839227_p0.webp","99693557_p0.webp","87977808_p0.webp","98215752_p0.webp","97312948_p0.webp","97618836_p0.webp","85543107_p0.webp","89261893_p0.webp","97744644_p0.webp","102162661_p0.webp","101036223_p0.webp","85030428_p0.webp","95852258_p0.webp","88695126_p0.webp","88127990_p0.webp","89905880_p0.webp","88450801_p0.webp","92229768_p0.webp","96965922_p0.webp","93187055_p0.webp","94974343_p0.webp","95640265_p0.webp","87550307_p0.webp","92080599_p0.webp","90842631_p0.webp","85998905_p0.webp","93068198_p0.webp","88640994_p0.webp","83935073_p0.webp","101462757_p0.webp","90080062_p0.webp","86644511_p0.webp","83902210_p0.webp","91501751_p0.webp","95732886_p0.webp","84720532_p0.webp","95734855_p0.webp","95527533_p0.webp","80567870_p0.webp","86612443_p0.webp","101157273_p0.webp","84396140_p0.webp","94332366_p0.webp","87541340_p0.webp","85109066_p0.webp","102241526_p0.webp","84699476_p0.webp","93526437_p0.webp","83266050_p0.webp","88504507_p0.webp","101490359_p0.webp","99214743_p0.webp","93414470_p0.webp","84655195_p0.webp","85612639_p0.webp","90575757_p0.webp","96160341_p0.webp","90863688_p0.webp","86221335_p0.webp","101573593_p0.webp","92791077_p0.webp","101462661_p0.webp","79627564_p0.webp","95681846_p0.webp","92004086_p0.webp","96514892_p0.webp","89639050_p0.webp","101553430_p0.webp","84672028_p0.webp","85011957_p0.webp","93083916_p0.webp","84824171_p0.webp","93798842_p0.webp","83658524_p0.webp","100784767_p0.webp"]
    ],
    "yuri" => [
        "CDN_dir" => "/yuri/",
        "local_dir" => "./library/yuri/",
        "image_list" => ["83928473_p0.webp","102567973_p0.webp","82542737_p0.webp","91194235_p0.webp","60537176_p0.webp","97333993_p0.webp","78612478_p0.webp","56907845_p0.webp","89172772_p1.webp","93122161_p0.webp","94908514_p0.webp","87857349_p0.webp","94106688_p0.webp","84571732_p0.webp","100475697_p0.webp","87710894_p0.webp","99192203_p0.webp","74822118_p0.webp","94118936_p0.webp","88603735_p0.webp","68146165_p0.webp","94277636_p0.webp","83245109_p0.webp","83419740_p0.webp","99066456_p0.webp","96080487_p0.webp","64535082_p0.webp","83088427_p0.webp","100385857_p0.webp","98717421_p0.webp","101704443_p0.webp","87108518_p0.webp","85769778_p0.webp","85397299_p0.webp","100339292_p0.webp","61198628_p0.webp","99906124_p0.webp","97083888_p0.webp","100056160_p0.webp","78341619_p0.webp","88609517_p1.webp","91885680_p0.webp","100236457_p0.webp","98259659_p0.webp","74451788_p0.webp","22386076_p0.webp","74010555_p0.webp","99870140_p0.webp","85262834_p0.webp","98089060_p0.webp","37320565_p0.webp","85077923_p0.webp","94173069_p0.webp","94955814_p0.webp","77240141_p0.webp","85524069_p0.webp","78875099_p0.webp","79906379_p0.webp","100567610_p0.webp","77734148_p0.webp","59649097_p0.webp","98281111_p0.webp","100039624_p0.webp","101473348_p0.webp","85460920_p0.webp","86141867_p0.webp","76771613_p0.webp","80567870_p0.webp","100960965_p0.webp","91191150_p0.webp","100930872_p0.webp","78663174_p0.webp","97495003_p0.webp","82135005_p0.webp","87745777_p0.webp","74635611_p0.webp","97146726_p0.webp","102825244_p0.webp","100365012_p0.webp","78173773_p0.webp","97941568_p0.webp","75854071_p0.webp","79851098_p0.webp","73081851_p0.webp","80598441_p0.webp","96099152_p0.webp","90153492_p0.webp","85465269_p0.webp","85376171_p0.webp","101811971_p0.webp","62519151_p0.webp","89172772_p2.webp","100376755_p0.webp","94394808_p0.webp","70246393_p0.webp","78491685_p0.webp","65293627_p0.webp","83101983_p0.webp","100780504_p0.webp","85730157_p1.webp","84350788_p0.webp","72300506_p0.webp","91303180_p0.webp","77359441_p0.webp","69938888_p0.webp","98201866_p0.webp","99435308_p0.webp"]
    ],
    "kano-horizontal" => [
        "CDN_dir" => "/kano/horizontal/",
        "local_dir" => "./library/kano/horizontal/",
        "image_list" => ["kano_pc_28.webp","kano_pc_25.webp","kano_pc_18.webp","kano_pc_23.webp","kano_pc_09.webp","kano_pc_31.webp","kano_pc_03.webp","kano_pc_12.webp","kano_pc_27.webp","kano_pc_32.webp","kano_pc_19.webp","kano_pc_15.webp","kano_pc_29.webp","kano_pc_21.webp","kano_pc_11.webp","kano_pc_26.webp","kano_pc_13.webp","kano_pc_16.webp","kano_pc_02.webp","kano_pc_17.webp","kano_pc_07.webp","kano_pc_30.webp","kano_pc_06.webp","kano_pc_04.webp","kano_pc_24.webp","kano_pc_01.webp","kano_pc_20.webp","kano_pc_14.webp","kano_pc_05.webp","kano_pc_10.webp","kano_pc_08.webp","kano_pc_22.webp"]
    ],
    "kano-vertical" => [
        "CDN_dir" => "/kano/vertical/",
        "local_dir" => "./library/kano/vertical/",
        "image_list" => ["kano_mobile_05.webp","kano_mobile_06.webp","kano_mobile_02.webp","kano_mobile_04.webp","kano_mobile_01.webp","kano_mobile_03.webp"]
    ]
];

/**
 * 获取用户配置
 *
 * @param string $name
 * @return string|array
 */
function get_user_config($name){

    global $user_config;

    return $user_config[$name];
}

/**
 * 获取图片的CDN URL
 *
 * @return string
 */
function get_cdn_url(){

    global $cdn_list;

    if(get_user_config('diff_domain') == 'true') {

        if (!isset($_SERVER['HTTP_REFERER'])) return $cdn_list['cloudflare']; //空referer返回CF cdn

        $url = $_SERVER['HTTP_REFERER'];
        $host_name = parse_url($url, PHP_URL_HOST); //获取域名
        $referer_list = get_user_config('referer_list');

        if (in_array($host_name, $referer_list)) {
            return $cdn_list[get_user_config('cdn_choose')]; //在列表内的域名返回选择的cdn
        } else {
            return $cdn_list['cloudflare']; //不在列表内的域名返回cf cdn
        }      
    }
    return $cdn_list[get_user_config('cdn_choose')]; //未开启域名分流策略,返回选择的cdn
}

/**
 * 获取图片路径
 *
 * @param string $album_name
 * @param boolean $local
 * @return string
 */
function get_image_path($album_name, $local){

    global $image_info;

    $cdn_url = get_cdn_url();
    $max = count($image_info[$album_name]['image_list']) - 1;
    $pick = rand(0,$max);
    $image_url = $cdn_url . $image_info[$album_name]['CDN_dir'] . $image_info[$album_name]['image_list'][$pick];
    $image_local_dir = $image_info[$album_name]['local_dir'] . $image_info[$album_name]['image_list'][$pick];

    return $local? $image_local_dir : $image_url;

}

/**
 * 输出图片
 *
 * @param string $album_name
 * @return mixed
 */
function output_image($album_name){

    if (get_user_config('output') == 'cdn') {
        $path = get_image_path($album_name, false);
        return header("Location:".$path);
    }
    if (get_user_config('output') == 'pass') {
        $path = get_image_path($album_name, true);
        ob_clean();
        $imgData = file_get_contents($path); //获取图片二进制流
        $type = getimagesize($path)['mime']; //获取图片文件类型
        header("Content-Type:{$type}");
        echo $imgData; //输出二进制图片
    }
}

/**
 * 格式化URL参数
 *
 * @param string $query
 * @return array|boolean
 */
function convert_url_query($query){

    if (!$query) return false;
    $query_parts = explode('&', $query);
    $params = array();

    foreach ($query_parts as $param) {

        $item = explode('=', $param);
        if (empty($item[0])) {
            $item[0] = 'undefined';
        }
        if (empty($item[1])) {
            $item[1] = 'undefined';
        }
        $params[$item[0]] = $item[1];
    }
    return $params;
}

/**
 * 判断客户端是否是移动端
 *
 * @return boolean
 */
function is_mobile(){

    $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'Unknown';
    $mobileAgents = array(
        'iPhone',          // iPhone
        'iPod',            // iPod touch
        'Android',         // Android
        'Windows Phone',   // Windows Phone
        'BlackBerry',      // BlackBerry
        'webOS',           // Palm Pre/Pixi
        'Mobile',          // Generic mobile devices
        'Tablet',          // Generic tablets
    );

    foreach ($mobileAgents as $agent) {
        if (strpos($userAgent, $agent) !== false) {
            return  true;
        }
    }
    return false;
}

$arr_query = convert_url_query($_SERVER['QUERY_STRING']);

if ($arr_query && isset($arr_query['type']) && $arr_query['type'] == 'bg') {
    if (isset($arr_query['album']) && array_key_exists($arr_query['album'], $image_info)) {
        output_image($arr_query['album']);
    } else {
        if (is_mobile()) {
            output_image(get_user_config('mobile_default_album'));
        } else {
            output_image(get_user_config('default_album'));
        } 
    }
} elseif ($arr_query && isset($arr_query['album']) && array_key_exists($arr_query['album'], $image_info)) {
    output_image($arr_query['album']);
} else {
    output_image(get_user_config('default_album'));
}

exit();
?>

特色

目前共三个相册:原神、yuri、kano,大部分图片收集自P站,人肉精选。图片比例约为16:9,分辨率2160P。原始图片通过PhotoShop使用“保留细节2.0”超分(或超采样缩放)至4K,后在PS中转码为webp格式,在质量与图片体积中平衡取舍。

7个自定义参数:

  • output:cdn,使用CDN输出;pass,使用本机二进制输出
  • cdn_choose:选择哪个CDN
  • default_album:未指定相册或URL参数错误时默认输出的相册
  • mobile_default_album:移动端请求时,若未指定相册或参数错误,默认输出的相册
  • diff_domain:是否使用域名分流策略,开启后referer_list里的域名会使用cdn_choose里的CDN,其它域名使用CloudFlare CDN
  • referer_list:域名分流列表
  • cdn_list:可用的cdn列表,随心切换

请确保数组里的文件名和磁盘(或CDN)中的文件对得上,文件夹结构一致。需要修改的话,两者都要修改,否则404。

可以配置多个CDN地址,如CDN异常可在API中快速进行切换,前端无需调整。

output选择为pass时,不使用CDN时不做302跳转,直接使用本机进行二进制输出,对服务器性能有略微的影响,服务器带宽小不建议使用直出的方式。

API代码未作任何输入校验和错误处理。

图包下载:library.zip

图片文件名即为PIXIV ID,图片均收集自网络,非商业化使用,如有侵权,请联系我删除!

如何使用

基本使用

API URL:https://api-images.kanochan.net/api.php

https://api-images.kanochan.net/api.php

将图片URL替换成上面的API URL即可,同一页面多次引用在末尾加上随机字符以做区分,如:

https://api-images.kanochan.net/api.php?250

进阶使用

API URL:https://api-images.kanochan.net/api.php?album=yuri&

https://api-images.kanochan.net/api.php?album=yuri&

album用于指定输出相册,格式:album=相册名称,未指定则以default_album中的相册进行输出。

可选的相册

图片一览

可用的CDN列表

唔,这是ilulu赞助的,需要refferer加白名单。

这是萝莉控ilolicon赞助的,可以托管5GB的图片哦,快联系TA吧

使用Cloudflare,速度随缘。

  • .......正在等待更多大佬赞助CDN(划掉)

一些帮助

这个小函数可以帮你把文件夹里的图片输出为数组,本来想集成进API里,算了算了。

<?php
/**
 * 获取图库数据
 * @param $dir   要查找的文件路径
 * @param $dirArray    存储文件名的数组
 * @param $albumName    相册名称,以目录来命名
 */
function getImgList($dir, &$dirArray)
{
    // 读取当前目录下的所有文件和目录(不包含子目录下文件)
    $filesList = scandir($dir);

    if (is_array($filesList)) {
        foreach ($filesList as $val) {
            // 跳过. 和 ..
            if ($val == '.' || $val == '..')
                continue;

            // 判断是否是目录
            if (is_dir($dir . '/' . $val)) {
               getImgList($dir . '/' . $val, $dirArray);  //遇到目录递归继续往下寻找
            } else {
               $albumName = end(explode('/',$dir));  //获取图片文件所在的目录名称
               $dirArray[$albumName]['imgDir'] = $dir;  //记录图片相对路径
               $dirArray[$albumName]['imgLib'][] = $val;  //记录图片文件名
            }
        }
    }
}
$imgList = array ();
$dir = './library';
getImgList($dir, $imgList);
print_r($imgList);
exit();
?>
この素晴らしい世界に祝福を!
最后更新于 2023-10-08