【共创稿事节】鸿蒙图像超分 · 壁纸适配工作台:三种屏幕比例、居中裁切、端侧 4× 超分、所见即所得
【共创稿事节】鸿蒙图像超分 · 壁纸适配工作台三种屏幕比例、居中裁切、端侧 4× 超分、所见即所得前五篇把端侧超分这个「单点能力」打磨得很顺了——单图重建、实时放大镜、批量落盘、相册直选每一步都验证了 HarmonyOS 端侧 NPU 推理的可用性。但都是技术演示视角选一张图、跑一遍模型、看对比。真实用户的诉求其实更朴素——「我想把这张照片做成手机壁纸」。这一篇换个视角从「做成壁纸」这个具体场景出发做一个把壁纸比例、居中裁切、端侧超分、导出尺寸串成一条链的工作台。同时借这个机会把前作里几个一直被忽略的坑——壁纸预设形同虚设、保存功能永远失败、结构体get访问器运行时崩——一次性修掉。工程地址LI_harmonyOS/Image-Super-Resolution/harmony-sr-studio运行环境HarmonyOS 7.0API 26 ArkTS 严格模式已在 Mate 90 Pro 模拟器7.0.0/26.0.0安装运行验证。包名com.example.harmonysrstudio为读取相册照片申请了ohos.permission.READ_IMAGEVIDEOuser_grant含 reason/usedScene。一、效果展示工作台的完整链路只有四步选壁纸规格 → 导入照片相册或内置演示→ 端侧超分 → 导出目标尺寸壁纸。以下截图均为模拟器真机运行演示模式与真机模式走同一套 UI。选好规格这里是「平板桌面」2560×1800并载入内置狗狗演示素材后预览区按32:18 的横屏比例铺开构图与最终壁纸一致——这就是「所见即所得」的核心预览什么样导出的壁纸就什么样往下滚动可以看到输入/工作/输出三个尺寸卡、处理方式按钮区。演示模式下明确标注「演示素材」「DEMO MODE」不会伪装成真实推理超分完成后进入对比态左侧「原始」、右侧「演示素材」中间一条可拖动的白色分割线。默认分割居中左右同源同构图、只分辨率不同把分割线一路拖到最左整个预览区就只剩右侧的高清结果方便单独检查细节切换到「手机壁纸」1440×3200 后预览区立刻按9:20 的窄竖条重新裁切——同一张狗狗图构图从横屏变成竖屏壁纸比例的差异一目了然二、这个 App 解决什么问题前五篇的超分输入都是「正方形或 4:3 的素材」对比的是「放大前 vs 放大后」。但壁纸是有明确目标尺寸和宽高比的手机 9:20、平板 32:18、方形封面 1:1。这就引出三个新命题比例不对就得裁一张 4:3 照片要当手机壁纸必须裁成 9:20否则两边黑边或拉伸变形超分和裁切要算好顺序先超分再裁还是先裁到工作尺寸再超分这直接决定 NPU 输入大小和最终清晰度结果要导出成精确的像素尺寸不是「放大 4 倍就行」而是「必须正好是 1440×3200」。这个工作台给出的答案是按预设宽高比居中裁切源图 → 缩放到目标尺寸的 1/4 作为超分工作输入 → 端侧 4× 超分正好得到目标像素 → 导出。核心思路是「工作尺寸 目标尺寸 / 4」让 Core Vision Kit 的固定 4 倍放大刚好等于目标分辨率。三、核心算法为什么工作尺寸是目标尺寸的 1/4这是本篇在算法上唯一需要想清楚的地方也是整条链路的「灵魂」。Core Vision Kit 的图像超分是固定 4 倍放大——输入W×H输出就是4W×4H不可调。而壁纸要求精确的目标像素如 1440×3200。两者要严丝合缝唯一的办法就是反推输入尺寸工作尺寸 目标尺寸 / 4 手机壁纸 1440×3200 → 工作输入 360×800 平板桌面 2560×1800 → 工作输入 640×450 方形封面 2048×2048 → 工作输入 512×512这样喂给 NPU 一张360×800的图输出正好1440×3200一次推理直接得到目标分辨率无需任何二次缩放。这套「反推法」有两个硬性约束要处理public async prepareInput(preset: WallpaperPreset): PromiseLoadedImage | null { if (!this.source) { return null; } const info: image.ImageInfo await this.source.getImageInfo(); const region: image.Region PhotoLabService.centerCrop(info.size.width, info.size.height, preset.width / preset.height); const working: image.Size this.workingSize(preset, region.size); const prepared: image.PixelMap | null await this.coverTo(this.source, working.width, working.height); if (!prepared) { return null; } return { lowPm: prepared, lowW: working.width, lowH: working.height, srcW: this.srcW, srcH: this.srcH }; }第一个约束是NPU 输入上限 2048。工作尺寸里最大的是方形封面的 512×512远小于 2048安全但如果素材本身分辨率不够比如内置狗狗演示图只有 640×408就退化为「裁切区域的 1/4」而不是目标的 1/4private workingSize(preset: WallpaperPreset, crop: image.Size): image.Size { let workW: number Math.max(1, Math.round(preset.width / SR_SCALE)); let workH: number Math.max(1, Math.round(preset.height / SR_SCALE)); if (workW crop.width || workH crop.height) { // 素材分辨率不足以支撑目标工作尺寸改为素材裁切区域的 1/4 workW Math.max(1, Math.round(crop.width / SR_SCALE)); workH Math.max(1, Math.round(crop.height / SR_SCALE)); } const cap: number Math.min(1, SR_MAX_EDGE / Math.max(workW, workH)); return { width: Math.max(MIN_WORK_EDGE, Math.round(workW * cap)), height: Math.max(MIN_WORK_EDGE, Math.round(workH * cap)) }; }第二个约束是先裁后缩。centerCrop先把源图按目标宽高比居中裁出一块构图不变coverTo再把这块缩放到工作尺寸。这样最终壁纸的构图、裁切位置在预览阶段就完全确定。四、工程结构harmony-sr-studio/ ├── entry/src/main/ │ ├── ets/ │ │ ├── pages/Index.ets # 三态页面、规格切换、滑动对比、导出 │ │ └── common/ │ │ ├── PhotoLabModels.ets # LoadedImage / ProcessResult / 壁纸预设 │ │ ├── PhotoLabService.ets # 单例服务源管理/裁切/NPU超分/落盘 │ │ ├── PixelOps.ets # 像素读取 / 双线性基线 / 梯度能量 │ │ └── RealImageSuperResolutionService.ets # Core Vision Kit 官方接入参考 │ └── resources/rawfile/demo/ # 狗狗演示素材同源低清/高清 └── AppScope/壁纸预设用一个常量数组统一定义UI 和服务端都从这一个地方取避免「UI 显示一套、实际处理另一套」export interface WallpaperPreset { name: string; width: number; height: number; } /** 内置壁纸规格 */ export const WALLPAPER_PRESETS: WallpaperPreset[] [ { name: 手机壁纸, width: 1440, height: 3200 }, { name: 平板桌面, width: 2560, height: 1800 }, { name: 方形封面, width: 2048, height: 2048 } ];服务沿用系列前作的单例 双模式设计但多了一个关键角色——输入源source。它持有解码后的源图 PixelMap所有「按预设裁切」都基于这个源这样切换规格时能重新裁切而不是拿着旧裁切结果继续用。五、核心实现5.1 三态状态机空态 / 预览 / 结果整个页面用一个stage字段驱动三态互斥build()里按状态渲染没有命令式跳转type ScreenStage empty | preview | result;empty空态引导提示「导入一张照片开启细节重建」preview已载入素材、按当前规格裁切好显示「待增强」等用户点「开始图像超分」result超分完成进入滑动对比主按钮变为「导出壁纸」。预览区高度不是写死的而是随壁纸比例动态计算宽度固定高度 宽度 × 目标高宽比再夹在[200, 360]之间。这样手机壁纸是窄竖条、平板桌面是横屏、方形封面是正方形视觉上直接体现比例差异private previewHeight(): number { const preset: WallpaperPreset this.currentPreset(); const width: number this.previewWidth 0 ? this.previewWidth : PREVIEW_FALLBACK_WIDTH; const raw: number width * preset.height / preset.width; return Math.max(PREVIEW_MIN_HEIGHT, Math.min(PREVIEW_MAX_HEIGHT, Math.round(raw))); }5.2 Cover 适配居中裁切 原生缩放「把任意比例源图变成目标比例壁纸」用的是标准的Cover 适配先居中裁切到目标宽高比再等比缩放到目标尺寸。两步都走系统原生PixelMap操作不做任何 JS 逐像素处理private async coverTo(src: image.PixelMap, targetW: number, targetH: number): Promiseimage.PixelMap | null { let clone: image.PixelMap | null null; try { const info: image.ImageInfo await src.getImageInfo(); const sw: number info.size.width; const sh: number info.size.height; if (sw 0 || sh 0 || targetW 0 || targetH 0) { return null; } const region: image.Region PhotoLabService.centerCrop(sw, sh, targetW / targetH); clone await src.clone(); if (region.size.width ! sw || region.size.height ! sh) { await clone.applyCrop(region); } const fx: number targetW / region.size.width; const fy: number targetH / region.size.height; if (Math.abs(fx - 1) 0.001 || Math.abs(fy - 1) 0.001) { await clone.applyScale(fx, fy, image.AntiAliasingLevel.LOW); } return clone; }关键细节先 clone 再原地改。applyCrop/applyScale都是原地操作直接改会污染源图所以先clone()出一份再裁。裁切区域的计算是纯数学——比较源宽高比和目标宽高比谁宽裁谁private static centerCrop(srcW: number, srcH: number, targetAspect: number): image.Region { const srcAspect: number srcW / srcH; let cropW: number srcW; let cropH: number srcH; if (srcAspect targetAspect) { cropW Math.max(1, Math.min(srcW, Math.floor(srcH * targetAspect))); } else if (srcAspect targetAspect) { cropH Math.max(1, Math.min(srcH, Math.floor(srcW / targetAspect))); } const x: number Math.max(0, Math.floor((srcW - cropW) / 2)); const y: number Math.max(0, Math.floor((srcH - cropH) / 2)); return { size: { width: cropW, height: cropH }, x: x, y: y }; }5.3 规格切换丢弃旧结果、重新裁切这是把「壁纸预设」从摆设变成功能的关键。切换规格时不是简单改个 label而是释放旧的低清图和结果用新比例对源图重新裁切private async selectPreset(index: number): Promisevoid { if (this.busy || index this.presetIndex) { return; } this.presetIndex index; this.savedLabel ; if (this.stage empty) { return; } // 已有素材丢弃旧结果按新比例重新裁切输入 this.busy true; try { const label: string this.service.isDemoSource() ? 内置演示素材 : 相册照片; await this.prepareInput(label); } finally { this.busy false; } }prepareInput内部先释放旧的lowPm和result再按新预设裁切出新的工作图。这里有一个很容易犯的内存错误必须先 release 旧 PixelMap 再赋新值否则切换几次规格就泄漏好几张图private async prepareInput(label: string): Promiseboolean { const loaded: LoadedImage | null await this.service.prepareInput(this.currentPreset()); if (!loaded || !loaded.lowPm) { this.releaseImages(); this.stage empty; this.imageSource 请选择一张照片开始; this.toast(按所选规格裁切失败请重试); return false; } if (this.result) { if (this.result.hdPm) { this.result.hdPm.release(); } this.result null; } if (this.lowPm) { this.lowPm.release(); } this.lowPm loaded.lowPm; this.sourceWidth loaded.srcW; this.sourceHeight loaded.srcH; this.imageSource ${label} · ${loaded.srcW} × ${loaded.srcH}; this.stage preview; this.split 50; return true; }5.4 处理主流程NPU 超分 演示回退 增益量化process一条链路产出 UI 需要的全部东西真机模式走 NPU失败或演示模式回退到「同源高清参考」用同一源图裁出目标尺寸保证对比图构图一致最后统一裁切到精确目标像素并算清晰度增益public async process(lowPm: image.PixelMap, lowW: number, lowH: number, useReal: boolean, preset: WallpaperPreset): PromiseProcessResult | null { let raw: image.PixelMap | null null; try { if (useReal this.analyzer) { raw await this.superResolve(lowPm); } else if (this.source) { // 演示模式用同一输入源裁切出高清参考保证前后对比同源同构图 raw await this.coverTo(this.source, preset.width, preset.height); } if (!raw) { return null; } const hd: image.PixelMap | null await this.coverTo(raw, preset.width, preset.height); raw.release(); if (!hd) { return null; } const gain: number await this.estimateGain(lowPm, lowW, lowH, hd); return { hdPm: hd, hdW: preset.width, hdH: preset.height, gain: gain }; }真机 NPU 调用本身与系列前作完全一致——因为工作尺寸最大才 640×450远小于 2048 上限一次process()整图出结果private async superResolve(lowPm: image.PixelMap): Promiseimage.PixelMap | null { if (!this.analyzer) { return null; } try { const request: visionBase.Request { inputData: { pixelMap: lowPm } }; const response: imageSuperResolution.ISPResponse await this.analyzer.process(request); return response.pixelMap; } catch (error) { const err error as Error; hilog.error(DOMAIN, TAG, super resolution failed: %{public}s, err.message); return null; } }5.5 增益评估先降采样到小网格避免 JS 逐像素卡顿清晰度增益用系列前作同口径的梯度能量邻域亮度差绝对值和越高越清晰但要比较「超分结果」和「低清双线性放大」两者必须同尺寸。问题是结果可能是 2560×1800 这种大图在 JS 里逐像素遍历几百万像素会卡好几秒。解法是先把两边都用原生applyScale缩到192px小网格JS 只遍历约 3.7 万像素毫秒级完成private async estimateGain(lowPm: image.PixelMap, lowW: number, lowH: number, hdPm: image.PixelMap): Promisenumber { const hdInfo: image.ImageInfo await hdPm.getImageInfo(); const hdW: number hdInfo.size.width; const hdH: number hdInfo.size.height; const longEdge: number Math.max(hdW, hdH); if (longEdge 0) { return 0; } const ratio: number Math.min(1, METRIC_EDGE / longEdge); const gridW: number Math.max(2, Math.round(hdW * ratio)); const gridH: number Math.max(2, Math.round(hdH * ratio)); const lowBuffer: Uint8Array | null await readRgba(lowPm); if (!lowBuffer) { return 0; } const baseline: Uint8Array | null bilinearUpscaleTo(lowBuffer, lowW, lowH, gridW, gridH); if (!baseline) { return 0; } const baselineEnergy: number gradientEnergy(baseline, gridW, gridH); const highEnergy: number await this.downscaledEnergy(hdPm, gridW, gridH); if (baselineEnergy 0) { return 0; } return Math.max(0, Math.min(99, Math.round((highEnergy / baselineEnergy - 1) * 100))); }5.6 滑动对比Stack 叠两层 clip 裁剪对比控件没用任何像素混合思路和前作一致但做了简化Stack底层放结果图满铺上层放一个宽度为split%、溢出裁剪的子 Stack 包住原始图再压一条白色分割线和两枚标签。拖动手势只改一个 0~100 的State splitStack({ alignContent: Alignment.Center }) { if (this.result?.hdPm this.stage result) { Image(this.result.hdPm) .width(100%) .height(height) .objectFit(ImageFit.Cover) .borderRadius(16) Stack({ alignContent: Alignment.Start }) { Image(this.lowPm) .width(this.previewWidth 0 ? this.previewWidth : PREVIEW_FALLBACK_WIDTH) .height(height) .objectFit(ImageFit.Cover) } .width(${this.split}%) .height(height) .clip(true) Column() .width(2) .height(height) .backgroundColor(#FFFFFF) .position({ x: this.dividerX() - 1, y: 0 })两个几何细节两张图都必须objectFit(ImageFit.Cover)且同尺寸同高度否则分割线两边错位上层子 Stack 用.clip(true)把超出split%宽度的部分裁掉分割线位置由containerWidth() * split / 100算出横竖屏、折叠屏都不会算错。5.7 结果导出按预设裁切后写 PNG 沙箱导出沿用系列的零权限方案但多了一步——先按预设再裁切缩放一次确保落盘的像素尺寸就是目标尺寸public async exportWallpaper(hdPm: image.PixelMap, preset: WallpaperPreset, name: string): PromisePackResult | null { const fitted: image.PixelMap | null await this.coverTo(hdPm, preset.width, preset.height); if (!fitted) { return null; } try { return await this.writePng(fitted, name); } finally { fitted.release(); } }文件名用{宽}x{高}_{时间戳}保证多次保存不覆盖写盘用packToData→openSync→writeSync→fsyncSync→closeSync最后回显沙箱路径和文件大小。六、踩坑实录三个隐蔽的「能编译但跑挂/失效」这一篇把工程从「能编译」打磨到「真机稳定」修掉了三个非常典型的 HarmonyOS 坑。它们有个共同点编译全绿、静态检查不报错但一跑就出问题。6.1 结构体get访问器编译通过、运行时undefined最致命的一个。为了取当前壁纸规格我最开始写了一个访问器// ❌ 错误写法ArkTS Component struct 不支持 get/set 访问器privategetpreset():WallpaperPreset{returnWALLPAPER_PRESETS[this.presetIndex];}编译完全通过没有任何报错。但真机一进首帧渲染就 jscrashTypeError: Cannot read property width of undefined at initialRender (Index.ets:437:37)原因是 ArkTS 的Component struct不支持get/set访问器——它在编译产物里没有被正确绑定this.preset运行时就是undefined再去取.width直接崩。改成普通方法立刻解决/** 取当前壁纸规格ArkTS 结构体不支持 get 访问器必须用普通方法 */ private currentPreset(): WallpaperPreset { const presets: WallpaperPreset[] WALLPAPER_PRESETS; const index: number (presets.length 0 this.presetIndex 0 this.presetIndex presets.length) ? this.presetIndex : 0; return presets[index]; }教训ArkTS 结构体里访问派生数据一律用方法不要用get。这类「编译能过、运行时崩」的问题只能真机/模拟器跑出来。6.2fileIo.accessSync对不存在路径是抛异常不是返回 false保存功能一开始永远失败。原写法想「目录不存在就创建」// ❌ 错误写法accessSync 对不存在路径抛异常永远走不到 mkdirSyncif(!fileIo.accessSync(directory)){fileIo.mkdirSync(directory,true);}但accessSync的语义是「存在返回 true不存在直接抛异常」所以!accessSync(...)这个判断在目录不存在时根本执行不到——异常先抛了被外层 catch 吞掉首图保存必定失败。正确做法是 try/catch 里尝试访问失败再创建private ensureDirectory(dir: string): boolean { try { if (fileIo.accessSync(dir)) { return true; } } catch (error) { // 目录不存在时 accessSync 会抛异常落到下方创建逻辑 } try { fileIo.mkdirSync(dir, true); return true; } catch (error) { const err error as Error; hilog.error(DOMAIN, TAG, create directory failed: %{public}s, err.message); return false; } }6.3 rawfile 解码Uint8Array.buffer可能带非零偏移读内置演示素材时一开始直接image.createImageSource(content.buffer)。大部分时候能解码但偶发解码错位——getRawFileContent返回的Uint8Array可能带有非零byteOffset直接传底层buffer会把整个共享缓冲区而不是这个视图喂给解码器。必须按视图切片const content: Uint8Array await this.context.resourceManager.getRawFileContent(name); // Uint8Array 可能带有非零 byteOffset直接传 buffer 会导致解码错位必须按视图切片 const data: ArrayBuffer content.buffer.slice(content.byteOffset, content.byteOffset content.byteLength); source image.createImageSource(data); return await source.createPixelMap({ desiredPixelFormat: image.PixelMapFormat.RGBA_8888 });这三个坑在踩坑清单速查表里都有对应条目是这一篇最有价值的「实战经验」。七、权限配置user_grant 权限的三要素从相册读照片需要ohos.permission.READ_IMAGEVIDEO这是个user_grant 权限module.json5里必须同时声明reason和usedScene缺一不可而且reason必须是$string:资源引用不能写中文文本{ name: ohos.permission.READ_IMAGEVIDEO, reason: $string:permission_read_imagevideo_reason, usedScene: { abilities: [EntryAbility], when: inuse } }对应的字符串资源放在resources/base/element/string.json{name:permission_read_imagevideo_reason,value:用于读取您选择的图片或视频进行端侧超分辨率处理。}少了reason/usedScene会报00303218 Configuration Errorreason写了纯文本会报00303038 Schema validate failed。这两个错都是在 PreBuild 阶段卡死先把配置写对才能进入真正的 ArkTS 编译。八、真机 / 模拟器运行指南演示模式默认点「载入演示图」用内置狗狗素材不调 NPU任何设备都能跑通「选规格 → 预览 → 超分 → 对比 → 导出」全流程结果明确标注「演示素材」真机模式点「从相册选择」在系统相册选任意图会真实走一遍端侧 NPU 4× 超分。若设备不支持 Core Vision Kit会自动回退演示素材并 toast 提示「真实超分需要支持的设备」不会伪装成成功结果保存在沙箱filesDir/wallpaper_sr_out/{宽}x{高}_{时间戳}.png取出方式hdc shell ls /data/app/el2/100/base/com.example.harmonysrstudio/haps/entry/files/wallpaper_sr_out hdc file recv /data/app/el2/100/base/com.example.harmonysrstudio/haps/entry/files/wallpaper_sr_out ./out命令行构建需要把 DevEco 自带的 JBR 加进PATH否则打包阶段报spawn java ENOENT$env:DEVECO_SDK_HOMEC:\Program Files\Huawei\DevEco Studio\sdk$env:JAVA_HOMEC:\Program Files\Huawei\DevEco Studio\jbr$env:PATHC:\Program Files\Huawei\DevEco Studio\jbr\bin;$env:PATHnodeC:\Program Files\Huawei\DevEco Studio\tools\hvigor\bin\hvigorw.js--mode module-p moduleentrydefault-p productdefault-p requiredDeviceTypephone assembleHap--analyzenormal--parallel--no-daemon九、踩坑清单速查表现象原因修法一进页面就 jscrashCannot read property width of undefinedArkTS struct 用了get访问器编译过但运行时返回undefined改用普通方法currentPreset()首次保存永远失败fileIo.accessSync对不存在路径抛异常!accessSync()走不到创建分支try/catch 访问失败再mkdirSync(dir, true)内置素材偶发解码错位getRawFileContent返回的Uint8Array带非零byteOffset直接传.bufferbuffer.slice(byteOffset, byteOffsetbyteLength)按视图切片大图增益计算卡好几秒JS 逐像素遍历几百万像素原生applyScale先缩到 192px 网格再算梯度能量切换规格后预览构图不变只改了 label没重新裁切保留源图source切换时prepareInput重新裁切分割线两边画面错位两张图objectFit/尺寸/高度不一致都用Cover 同宽高上层clip(true)裁split%超分结果尺寸不是目标像素直接用 NPU 输出没按预设裁切工作尺寸 目标/4输出再coverTo到精确目标PreBuild 报00303218user_grant 权限缺reason/usedScene补两字段PreBuild 报00303038reason写了中文纯文本改$string:资源引用打包报spawn java ENOENTshell 缺 JDK把 DevEco 自带jbr\bin加进PATH十、总结至此图像超分系列走完第六步从「技术演示」走向「场景闭环」。这一篇的核心不是又接了一个新 API而是把端侧超分放进一个真实的产品场景里重新审视——壁纸有明确的尺寸和比例超分不能再是「放大 4 倍看效果」而要「精确产出 1440×3200 这块能直接设成壁纸的图」。为此我们反推出「工作尺寸 目标尺寸 / 4」的输入策略用 Cover 适配解决任意比例的居中裁切用保留源图 重新裁切让规格切换真正生效再把前作里潜伏的三个运行时坑get访问器崩溃、accessSync语义、Uint8Array偏移一次性填平。至此从单图重建、实时放大镜、批量工作台、相册直选到今天的壁纸适配端侧超分这条线已经覆盖了「能力验证 → 交互增强 → 工程批量化 → 真实输入 → 场景落地」的完整路径。下一步可以继续往「设置成系统壁纸」这个最后一步走需要setWallpaper相关能力或者把裁切框做成可手动拖拽调整构图的交互——那就留给下一篇了。工程里RealImageSuperResolutionService.ets保留了 Core Vision Kit 的官方接入参考真机上把useReal置真即可切换到 NPU 推理模拟器/不支持设备自动回退演示素材保证任何环境都能完整体验。壁纸比例与尺寸的工作台已经搭好剩下的就是把每一张图都适配到它的屏幕上。

相关新闻

Claude记忆层设计:用SQLite+嵌入向量构建轻量可控状态管理

Claude记忆层设计:用SQLite+嵌入向量构建轻量可控状态管理

1. 项目概述:一个被误读的命名陷阱,以及它背后的真实技术逻辑“claude-mem”这个词最近在多个技术社区和开发者群组里高频出现,但几乎没人能说清它到底指什么。我翻遍了主流模型平台的公开文档、API变更日志和开发者论坛,确认了一…

2026/10/11 9:09:49 阅读更多 →
Harness Engineering:把代码库和流程改造成Agent友好型

Harness Engineering:把代码库和流程改造成Agent友好型

话说回来,你们有没有经历过这种场景:把一个挺成熟的 AI Coding Agent 丢进公司那套沉淀了五六年的代码库里,满怀期待让它改个需求,结果它要么在错误的文件里反复横跳,要么改完 A 模块顺手把 B 模块的公共函数给动了&am…

2026/10/11 9:09:49 阅读更多 →
代码知识图谱利器Graphify:把大型代码库变成可查询关系地图

代码知识图谱利器Graphify:把大型代码库变成可查询关系地图

在开源社区里,上一个让我对着截图愣半天神的项目,还是某个可视化前端组件。Graphify 能拿下 12.3 万星,靠的确实不是单纯的颜值。它解决的是所有开发者在某个阶段都会撞上的那面硬墙:代码库太大,关系太隐蔽&#xff0c…

2026/10/11 9:09:49 阅读更多 →

最新新闻

XSnow缓存策略完全指南:5种缓存策略如何让你的数据加载快人一步?

XSnow缓存策略完全指南:5种缓存策略如何让你的数据加载快人一步?

【免费下载链接】XSnow 💮基于RxJava2Retrofit2精心打造的Android基础框架,包含网络、上传、下载、缓存、事件总线、权限管理、数据库、图片加载,基本都是项目中必用功能,每个模块充分解耦,可自由拓展。 项目地址&…

2026/10/11 10:00:56 阅读更多 →
数字识别数据集:1000张图与VOC/COCO/YOLO标签格式转换及YOLO训练

数字识别数据集:1000张图与VOC/COCO/YOLO标签格式转换及YOLO训练

简介:这份资源面向计算机视觉入门与目标检测实践者,提供一套真实场景下的YOLO数字识别数据集,可用于训练和验证数字检测模型,适合课程设计、算法练手及小目标检测实验。压缩包共约2000个文件,整体14.07MB,包…

2026/10/11 10:00:56 阅读更多 →
YOLO烟盒数据集实战:从解压到训练全流程解析

YOLO烟盒数据集实战:从解压到训练全流程解析

简介:这份数据集面向YOLO系列算法目标检测场景,聚焦烟盒识别任务。压缩包内共有七百零三个文件,其中二百三十四张JPEG原图,每张均同时提供YOLO格式的TXT标签与VOC格式的XML标签,另含一份data.yaml配置文件。TXT标签存储…

2026/10/11 10:00:56 阅读更多 →
Claude提示词工程:结构化设计与可压测的实践方法论

Claude提示词工程:结构化设计与可压测的实践方法论

简介:本资源是一份面向AI提示工程学习者与Claude深度使用者的「加强版Claude提示词」实践指南,聚焦于提升模型响应质量的核心思考机制设计。它系统阐述了Claude必须遵循的无过滤、流式化、自适应的内在思考协议,涵盖思考触发条件、thinking代…

2026/10/11 10:00:56 阅读更多 →
SQLite 3.6.22 数据库快照解析与兼容性迁移指南

SQLite 3.6.22 数据库快照解析与兼容性迁移指南

简介:本资源为Oracle 10g R2(10.2.0.4)在Windows Vista/Server 2008 x64平台的生产级数据库部署包,面向DBA、企业级数据库运维工程师及Oracle高可用环境实践者,解决64位Windows环境下Oracle数据库实例初始化、参数配置…

2026/10/11 10:00:56 阅读更多 →
OpenBMC RAID管理模块:从底层驱动到Redfish全栈拆解

OpenBMC RAID管理模块:从底层驱动到Redfish全栈拆解

服务器运维圈子里聊 RAID,大家先入为主的印象往往是开机自检时按快捷键进的那套 RAID 配置界面,或者是操作系统里装个 storcli 敲命令行。但真正要在云端或数据中心做大规模带外管理时,RAID 的命脉其实握在 BMC 手里——OpenBMC 这个开源固件…

2026/10/11 9:59:56 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →