@clawhub-hitpawdev-35253341ee
Enhance images and videos using HitPaw's AI enhancement API
---
name: hitpaw-image-enhancer
description: Enhance images and videos using HitPaw's AI enhancement API
version: "1.0.3"
author: Nova (HitPaw-Official)
type: cli
entry: dist/cli.js
repository: https://github.com/HitPaw-Official/openclaw-skill-hitpaw-enhancer
keywords:
- image
- video
- enhancement
- upscale
- hitpaw
- ai
license: MIT
capabilities:
- image_enhancement
- image_upscaling
- photo_enhance
- video_enhancement
- video_upscaling
requirements:
node: ">=18"
packages:
- axios
- commander
- ora
- chalk
- fs-extra
environment:
variables:
- name: HITPAW_API_KEY
description: Your HitPaw API key
required: true
---
# HitPaw Image & Video Enhancer Skill
A powerful OpenClaw skill that integrates HitPaw's state-of-the-art AI enhancement technology for both **images** and **videos**. Enhance, upscale, restore, and denoise with multiple AI models.
---
## 🎯 Features
Based on the official [HitPaw API Documentation](https://developer.hitpaw.com/image/Introduction), this skill leverages industrial-grade AI models developed in-house by HitPaw's expert R&D team.
### Core Strengths
- **Quality**: Industry-defining quality fit for professional use cases, from commercial photography to archival restoration
- **Fidelity**: Preserves the original details and identities in the source images, ensuring the output remains true to the input
- **Efficiency**: Optimized for low latency and high throughput, capable of processing distinct enhancement tasks at scale
---
## 📸 Image Enhancement
According to the [Image API Introduction](https://developer.hitpaw.com/image/Introduction), our image processing services offer world-class capabilities designed to handle a wide variety of restoration scenarios:
### Key Capabilities
- **Upscale**: Output high-resolution images from low-resolution input files using standard or high-fidelity models
- **Face Recovery**: Ensure high-quality facial details, offering both "Clear" (soft/beauty) and "Natural" (textured/realistic) restoration options
- **Sharpen & Denoise**: Bring images into focus by removing blur and sensor noise while preserving the original structure
- **Generative Restoration**: Leverage Diffusion technology to reconstruct details in severely degraded portraits or general images
### Model Classes
The Image API offers two classes of AI models to suit different needs:
- **Standard Models**: Fast and efficient, prioritizing preserving original fidelity and details. Recommended for most professional and general restoration use cases
- **Generative Models**: Utilize Stable Diffusion to produce the highest quality outputs, capable of "imagining" missing details. Ideal for extremely low-quality inputs where traditional upscaling fails
#### Standard Models
As detailed in the [Available Models](https://developer.hitpaw.com/image/available-models) documentation:
| Model | Multiplier | Description | Best For |
|-------|------------|-------------|----------|
| `general_2x` / `general_4x` | 2x / 4x | General Enhance Model | General photos, landscapes |
| `face_2x` / `face_4x` | 2x / 4x | Portrait Model (Clear) | Soft/beauty style portrait enhancement |
| `face_v2_2x` / `face_v2_4x` | 2x / 4x | Portrait Model (Natural) | Natural/realistic portrait enhancement |
| `high_fidelity_2x` / `high_fidelity_4x` | 2x / 4x | High Fidelity Model | Professional photography, conservatively upscaling high-quality sources |
| `sharpen_denoise_1x` | 1x | Sharp Denoise Model | Aggressive denoising with sharpening |
| `detail_denoise_1x` | 1x | Detail Denoise Model | Gentle denoising with texture preservation |
#### Generative Models
Powered by Stable Diffusion technology:
| Model | Multiplier | Description | Best For |
|-------|------------|-------------|----------|
| `generative_portrait_1x/2x/4x` | 1x/2x/4x | Generative Portrait Model | Extremely low-quality portraits, "re-imagines" details |
| `generative_1x/2x/4x` | 1x/2x/4x | Generative Enhance Model | Heavily compressed or very low-resolution general images |
**Technical Highlights**:
- Generative models excel at texture generation and sharpening
- They can fill in missing details that traditional upscalers cannot recover
- Ideal for restoration tasks where source data is severely degraded
#### Example Image Use Cases
```bash
# General photo upscaling (landscape, architecture)
enhance-image -u landscape.jpg -m general_4x -o hd_landscape.jpg
# Portrait beautification (soft skin)
enhance-image -u selfie.jpg -m face_4x -o portrait_beautified.jpg
# Professional archival restoration (natural look)
enhance-image -u old_photo.png -m face_v2_2x -o restored.png --keep-exif
# Denoise grainy low-light photo
enhance-image -u night_photo.jpg -m sharpen_denoise_1x -o clean.jpg
# Generative reconstruction for severely degraded image
enhance-image -u blurry_face.jpg -m generative_portrait_2x -o ai_face.jpg
```
---
## 🎬 Video Enhancement
According to the [Video API Introduction](https://developer.hitpaw.com/video/Introduction), our video processing services provide industrial-grade solutions for restoring and upscaling video content:
### Key Capabilities
- **Video Upscale**: Convert SD or HD footage to 4K Ultra HD clarity using deep convolution and feature learning technologies
- **Portrait Restoration**: Specialized models to detect, stabilize, and enhance faces in video streams, removing motion blur and noise while maintaining identity
- **General Restoration**: A comprehensive solution based on GAN technology to de-noise, de-blur, and enhance details in general video content
- **Generative Reconstruction**: Utilizing Stable Diffusion for video to reconstruct textures and details in extremely low-quality footage
### Core Pillars
- **Temporal Stability**: Unlike image-only models, our video engines ensure smooth transitions between frames, eliminating flickering and jitter
- **Clarity**: Recovering fine details and removing compression artifacts common in streaming or legacy media
- **Performance**: Optimized inference times to handle heavy video processing workloads efficiently
### Model Classes
- **Restoration & Upscale (Standard)**: Models like Ultra HD and General Restore focus on cleaning up the footage and increasing resolution without altering the fundamental content. They rely on pixel-perfect accuracy and temporal consistency
- **Generative Video**: Uses advanced logic-based reconstruction. Designed for "impossible" restoration tasks where the source video lacks sufficient data, generating realistic textures and details to fill the gaps
#### Available Video Models
From the [Video Models Documentation](https://developer.hitpaw.com/video/available-models):
| Model | Description | Use Case |
|-------|-------------|----------|
| `ultrahd_restore_2x` | Ultra HD Model | High-definition upscale; natural-looking 1080p→4K |
| `general_restore_1x` / `2x` / `4x` | General Restore Model | General video restoration, de-noising, de-blurring |
| `portrait_restore_1x` / `2x` | Portrait Restore Model | Multi-face restoration with temporal stability |
| `face_soft_2x` | Video Face Soft Model | Facial beautification with consistent appearance |
| `generative_1x` | Generative Video Model | Extreme restoration of heavily degraded footage |
**Technical Highlights**:
- Generates realistic textures and eliminates flickering via multi-frame SD architecture
- Handles heavy compression, high-ISO noise, and complex motion blur
- Maintains identity consistency across frames
#### Example Video Use Cases
```bash
# Convert old 720p footage to 4K
enhance-video -u old_clip.mp4 -m ultrahd_restore_2x -r 3840x2160 -o 4k_remastered.mp4
# Restore grainy, noisy home video
enhance-video -u home_movie.avi -m general_restore_2x -r 1920x1080 -o cleaned.mp4
# Beautify faces in vlog/interview
enhance-video -u interview.mp4 -m face_soft_2x -r 1920x1080 -o soft_faces.mp4
# Stabilize and restore old family footage with multiple faces
enhance-video -u family_reunion.mov -m portrait_restore_2x -r 1920x1080 -o restored.mp4
# Generative AI restoration for severely degraded source
enhance-video -u heavily_compressed.mp4 -m generative_1x -r 1920x1080 -o regenerated.mp4
```
---
## 🚀 Why Choose HitPaw API?
**Industry-Leading Quality**: Professional-grade output suitable for commercial photography, archival restoration, and broadcast-quality video remastering
**Unparalleled Fidelity**: Strictly retains original details and subject identity, ensuring outputs remain true to inputs
**Comprehensive Model Catalog**: 16 specialized models covering virtually every restoration scenario
**Scalable Performance**: Optimized for low-latency, high-throughput workloads
---
## 📊 Quick Reference
### Image Model Selection Guide
| Scenario | Recommended Model |
|----------|-------------------|
| General photo upscale | `general_2x` or `general_4x` |
| Portrait beautification | `face_2x` or `face_4x` |
| Portrait natural look | `face_v2_2x` or `face_v2_4x` |
| Professional archival | `high_fidelity_2x` / `high_fidelity_4x` |
| Grainy low-light | `sharpen_denoise_1x` |
| Subtle denoise | `detail_denoise_1x` |
| Severely degraded | `generative_portrait_*` or `generative_*` |
### Video Model Selection Guide
| Scenario | Recommended Model |
|----------|-------------------|
| SD → 4K upscale | `ultrahd_restore_2x` |
| General cleanup | `general_restore_2x` |
| Interview/vlog beautification | `face_soft_2x` |
| Old home movies (multiple faces) | `portrait_restore_2x` |
| Severely compressed/ degraded | `generative_1x` |
---
## Installation
```bash
clawhub install hitpaw-image-enhancer
```
## Configuration
Set your HitPaw API key:
```bash
export HITPAW_API_KEY="your_api_key_here"
```
Or create a `.env` file in your OpenClaw workspace:
```
HITPAW_API_KEY=your_api_key_here
```
Get your API key at: https://playground.hitpaw.com/
Test the API directly in the browser: [HitPaw Playground →](https://playground.hitpaw.com/)
---
## 📸 Examples & Gallery
> **Note**: All screenshots below are from official HitPaw website (hitpaw.com), showcasing real enhancement results. Place additional examples in the `images/` folder.
### Image Enhancement Examples
#### General Upscale (2x/4x)
From official HitPaw documentation:
| Before | After |
|--------|-------|
|  |  |
*Demonstrates general image enhancement and upscaling capabilities*
**Use case**: Landscape photos, architecture, general photography
#### Unblur / Motion Blur Removal
| Before | After |
|--------|-------|
|  |  |
*Shows blur removal and sharpening effects*
**Use case**: Action shots, low-light photos, camera shake recovery
---
## 🎬 Video Enhancement Gallery
> Video screenshots coming soon. Currently using placeholder references.
| Scenario | Original Frame | Enhanced Frame |
|----------|----------------|----------------|
| General Upscale (1080p → 4K) |  |  |
| Portrait Restoration |  |  |
| Denoise & Cleanup |  |  |
See [images/README.md](images/README.md) for screenshot guidelines and recommended sources.
---
## 📊 Model Comparison Examples
### Face Enhancement: Clear vs Natural
| Clear (Soft/Beauty) | Natural (Realistic) |
|---------------------|---------------------|
|  |  |
- **Face Clear Model**: Soft skin, beautification style
- **Face Natural Model**: Preserves natural texture and pores
### Generative vs Standard Models
| Standard (general_4x) | Generative (generative_portrait_2x) |
|-----------------------|------------------------------------|
|  |  |
- **Standard models**: Fast, preserves original details
- **Generative models**: Reconstructs missing details, ideal for severely degraded inputs
---
# IMAGE COMMAND
## Usage: `enhance-image`
### Command Line Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `--url`, `-u` | string | **required** | URL of the image to enhance |
| `--output`, `-o` | string | `output.jpg` | Output file path |
| `--model`, `-m` | string | `general_2x` | Image model (see below) |
| `--extension`, `-e` | string | `.jpg` | Output extension (`.jpg`, `.png`, `.webp`) |
| `--dpi` | number | original | Target DPI for metadata |
| `--keep-exif` | boolean | false | Preserve EXIF data from original |
| `--poll-interval` | number | 5 | Polling interval in seconds |
| `--timeout` | number | 300 | Maximum wait time in seconds |
#### Available Image Models
| Model | Multiplier | Best For | DPI Support |
|-------|------------|----------|-------------|
| `general_2x` / `general_4x` | 2x / 4x | General photos, landscapes | ✅ |
| `face_2x` / `face_4x` | 2x / 4x | Portrait & face enhancement | ✅ |
| `face_v2_2x` / `face_v2_4x` | 2x / 4x | Improved face model | ✅ |
| `high_fidelity_2x` / `high_fidelity_4x` | 2x / 4x | High quality preservation | ✅ |
| `sharpen_denoise_1x` | 1x | Denoise & sharpen | ✅ |
| `detail_denoise_1x` | 1x | Detail preservation | ✅ |
| `generative_1x/2x/4x` | — | Generative Enhance Model | ❌ |
#### Examples
```bash
# Simple 2x upscale with general model
enhance-image -u photo.jpg -o enhanced.jpg -m general_2x
# Face enhancement 4x
enhance-image -u portrait.jpg -m face_4x -o portrait_4x.jpg --keep-exif
# High fidelity with custom DPI
enhance-image -u old-photo.png -m high_fidelity_2x -dpi 300 -o hd.png
# Batch processing
for img in *.jpg; do
enhance-image -u "$img" -o "upscaled/$img" -m general_4x
done
```
---
# VIDEO COMMAND
## Usage: `enhance-video`
### ⚠️ Important Notes
- **Resolution is required** (`--resolution` or `-r`). Must be in `WIDTHxHEIGHT` format (e.g., `1920x1080`).
- Ensure target resolution does **not exceed max output resolution** (36 MP total pixels) per API limits.
- Video processing can take **minutes to hours** depending on length. Use `--timeout` to extend if needed.
- Input video must be at a **publicly accessible URL** (local files not directly supported).
### Command Line Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `--url`, `-u` | string | **required** | URL of the video to enhance |
| `--output`, `-o` | string | `output.mp4` | Output file path |
| `--model`, `-m` | string | `general_restore_2x` | Video model (see below) |
| `--resolution`, `-r` | string | **required** | Target resolution in WxH (e.g., `1920x1080`) |
| `--original-resolution` | string | — | Original resolution (e.g., `1280x720`) - optional |
| `--extension`, `-e` | string | `.mp4` | Output extension (`.mp4`, `.mov`, `.avi`) |
| `--fps` | number | — | Target FPS (preserves original if omitted) |
| `--keep-audio` | boolean | true | Preserve audio track |
| `--poll-interval` | number | 10 | Polling interval in seconds |
| `--timeout` | number | 600 | Maximum wait time in seconds |
#### Available Video Models
| Model | Description | Use Case |
|-------|-------------|----------|
| `general_restore_1x` / `2x` / `4x` | General video restoration | General upscaling |
| `face_soft_2x` | Face-softening enhancement | Portrait videos |
| `portrait_restore_1x` / `2x` | Portrait restoration | Face-focused content |
| `ultrahd_restore_2x` | Ultra HD upscaling | Highest quality upscale |
| `generative_1x` | Generative fill | AI-powered restoration |
#### Examples
```bash
# Upscale to 1080p using general_restore_2x
enhance-video -u input.mp4 -o output_1080p.mp4 -m general_restore_2x -r 1920x1080
# Upscale to 4K with specific original resolution
enhance-video -u clip.mov -o 4k.mov -m general_restore_4x -r 3840x2160 --original-resolution 1920x1080
# Denoise with portrait model
enhance-video -u portrait_video.avi -m portrait_restore_2x -r 1920x1080 -o clean_portrait.mp4
# Add color to B&W (if generative model supports)
enhance-video -u bw_vintage.mp4 -m generative_1x -r 1920x1080 -o colorized.mp4
```
---
## Coin Consumption
### Image Enhancement
- 2x/4x models: **~75 coins** per image
- 1x models: **~50 coins** per image
- Generative models: **~100+ coins** per image
### Video Enhancement
Coin costs depend on video length, model, and resolution. Approximate rates:
- Upscale models: **~200-400 coins** per minute
- Restoration models: **~150-300 coins** per minute
**Always check current rates** at: https://playground.hitpaw.com/
---
## Error Handling
Common errors and solutions:
| Error | Cause | Fix |
|-------|-------|-----|
| `Invalid API key` | Wrong or expired key | Update `HITPAW_API_KEY` |
| `Insufficient coins` | Account balance too low | Top up at HitPaw Playground |
| `Unsupported model` | Model name typo or not available | Check model table above |
| `Invalid extension` | Output format not supported | Use `.jpg/.png/.webp` for images; `.mp4/.mov/.avi` for videos |
| `Invalid video URL` | URL not publicly accessible | Ensure video is reachable via HTTPS |
| `Input/target resolution over limit` | Exceeds 36 MP total pixels (e.g., 7680x4320 = ~33 MP) | Reduce resolution |
| `Video duration over limit` | Video longer than 1 hour | Trim video first |
| `Rate limit exceeded` | Too many requests | Wait and retry with exponential backoff |
| `Video processing failed` | Corrupt video or unsupported codec | Try different input format or re-encode |
---
## Error Codes
The API returns structured error codes. Always check both HTTP status and the `error_code` field.
### General Errors
| error_code | HTTP Status | Message |
|------------|-------------|---------|
| 100400000 | 400 | No access |
| 100400001 | 400 | Invalid URL |
| 100400002 | 400 | Bad Request |
| 100401000 | 401 | Token is expired |
| 100403000 | 403 | Invalid request parameters |
| 100403001 | 403 | Access denied |
| 100403002 | 403 | You don't have permission to access this resource |
| 100429000 | 429 | Too many requests, please try again later |
| 100500000 | 500 | Internal error |
| 100500001 | 500 | Database error |
| 100500002 | 500 | Cache error |
| 100500003 | 500 | Failed to create file |
| 100500004 | 500 | Signature verification failed |
| 100500005 | 500 | Configuration error |
| 100500006 | 500 | Unknown error |
| 100500007 | 500 | Operation timeout |
### API-Specific Errors
| error_code | HTTP Status | Message |
|------------|-------------|---------|
| 110400000 | 400 | api_key is not valid |
| 110400002 | 400 | The task does not exist |
| 110400003 | 400 | The task failed, please try again |
| 110400005 | 400 | The model is not supported, please try again |
| 110400007 | 400 | The extension is not valid |
| 110400008 | 400 | The video URL is not valid |
| 110400009 | 400 | The input resolution is over limit |
| 110400010 | 400 | The target resolution is over limit |
| 110400011 | 400 | The video duration is over limit |
| 110402000 | 402 | The coins are not enough |
| 110402001 | 402 | The coins are not enough |
| 110402004 | 402 | The Demo try times exceeded |
### Error Response Format
```json
{
"error_code": 110400000,
"message": "api_key is not valid"
}
```
## Rate Limiting
- The API implements rate limiting to ensure fair usage
- Error code `100429000` will be returned if you exceed the rate limit
- Implement **exponential backoff** in your retry logic
## Best Practices
### Polling for Job Status
- Poll the `/api/task-status` endpoint at reasonable intervals (recommended: every 5–10 seconds)
- Implement exponential backoff for failed requests
- Set a maximum number of polling attempts to avoid infinite loops
- Check status values: `CONVERTING` (keep polling), `COMPLETED` (success), `ERROR` (failed)
### Error Handling
- Always check the HTTP status code AND `error_code` in the response
- Implement retry logic for transient errors (5xx errors)
- Do NOT retry 4xx client errors without first fixing the request
- Log error responses for debugging
### Resource Limits
- **Images**: Max input resolution 70 MP (Enhancement/Denoise) / 34 MP (Generative); Max output 432 MP (Enhancement/Denoise)
- **Videos**: Max output 36 MP total pixels; Duration 0.5s – 1 hour
- Verify file extension validity before submitting
### API Key Management
- Store API keys securely using environment variables
- Never commit API keys to version control
- Rotate API keys periodically
### File URL Requirements
- Ensure image and video URLs are publicly accessible
- Use HTTPS URLs
- Use **Pre-sign OSS Upload** for unreliable URLs: https://developer.hitpaw.com/common/oss-presign-put-api
## Technical Details
### API Compatibility
This skill implements the official HitPaw API as documented:
- **Base URL**: `https://api-base.hitpaw.com`
- **Image endpoint**: `POST /api/photo-enhancer`
- **Video endpoint**: `POST /api/video-enhancer`
- **Status endpoint**: `POST /api/task-status`
Both endpoints return a `job_id`. Use the status endpoint to poll until `COMPLETED`, then download from `res_url`.
### Polling Strategy
- **Images**: default poll every 5s, timeout 300s (5 min)
- **Videos**: default poll every 10s, timeout 600s (10 min)
- Implement **exponential backoff** when encountering 5xx errors or rate limit (429)
For longer videos, increase `--timeout` as needed (e.g., `--timeout 3600` for 1 hour).
### Resolution & Format Limits
**Image Model Specs**:
| Model Category | DPI Support | Max Input | Max Output | Formats |
|----------------|-----------|----------|----------|--------|
| Enhancement & Denoise (`general_*`, `face_*`, `high_fidelity_*`, `*_denoise_*`) | ✅ | 70 MP | 432 MP | bmp, jpeg, jpg, png, jfif, tga, tiff, webp, heif |
| Generative (`generative_*`, `generative_portrait_*`) | ❌ | 34 MP | 34 MP | Same formats |
**Video Model Specs**:
| Property | Limit |
|----------|-------|
| Max Input Resolution | No limit |
| Max Output | 36 MP total pixels |
| Duration | 0.5 seconds – 1 hour |
| Input Formats | dv, mlv, m2ts, m2t, m2v, nut, ser, 3g2, 3gp, asf, avi, divx, f4v, flv, h261, h263, m4v, mkv, mov, mp4, mpeg, mpeg4, mpg, mxf, ogv, rm, rmvb, webm, wmv, gif |
| Output Formats | mp4, mov, mkv, m4v, avi, gif |
**Examples**: 3840×2160 = 8.3 MP ✅, 7680×4320 = 33.2 MP ✅, 8192×4608 = 37.7 MP ❌
For videos, `resolution` is **required**. Choose based on your needs:
- Keep original size? Set `resolution` to original dimensions (use `--original-resolution` for better quality).
- Upscale? Multiply original width/height by factor (2x, 4x).
- Downscale? Rare but possible; just specify smaller dimensions.
### Audio Preservation
By default, `enhance-video` keeps the audio track (`--keep-audio`, default true). Use `--no-keep-audio` to strip audio.
---
## Support
- Image API Docs: https://developer.hitpaw.com/image/API-reference
- Video API Docs: https://developer.hitpaw.com/video/API-reference
- Playground: https://playground.hitpaw.com/
- Contact: [email protected]
This skill is an **unofficial integration** with HitPaw API. You must have a valid API key and comply with HitPaw's terms. The skill author is not responsible for any charges incurred.
## License
MIT © HitPaw-Official
FILE:DEV.md
# Development Guide
## Build
```bash
npm install
npm run build
```
This compiles TypeScript to JavaScript in the `dist/` directory.
## Test
### Images
```bash
export HITPAW_API_KEY=your_key
node dist/cli.js -u https://example.com/photo.jpg -o out.jpg -m general_2x
```
### Videos
```bash
export HITPAW_API_KEY=your_key
node dist/video-cli.js -u https://example.com/video.mp4 -o out.mp4 -m upscale_2x
```
## CLI Commands
- `enhance-image` - image enhancement (main entry)
- `enhance-video` - video enhancement
Options for both commands are similar; see `--help` for details.
## Publish to ClawHub
```bash
clawhub login
clawhub publish .
```
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make changes and ensure `npm run build` passes
4. Submit a Pull Request
---
## Notes
- Video API may not be fully documented; models listed based on HitPaw product pages.
- If API returns `Unsupported model`, check the official docs for latest model names.
- Video jobs can take a long time; adjust `--timeout` accordingly.
- Always test with a small video first to estimate coin consumption.
## Disclaimer
This skill integrates with HitPaw API. You must have a valid API key and comply with HitPaw's terms. The skill author is not responsible for any charges incurred.
FILE:README.md
# HitPaw Image & Video Enhancer
[](https://clawhub.com/skill/hitpaw-image-enhancer)
[](https://github.com/HitPaw-Official/openclaw-skill-hitpaw-enhancer)
[](https://clawhub.com/skill/hitpaw-image-enhancer)
> OpenClaw skill integrating HitPaw's AI-powered image and video enhancement API
## 🎯 Features
This skill brings HitPaw's professional-grade AI enhancement capabilities to OpenClaw, supporting 16 specialized models for images and videos.
### Core Capabilities
- **Image Enhancement**: 2x/4x upscaling, face recovery, denoise, generative restoration
- **Video Enhancement**: Upscale to 4K, portrait restoration, temporal stability
- **Async Processing**: Polling-based job tracking with real-time status
- **Coin Tracking**: Monitor API consumption per job
## 📸 Screenshots
<!-- Actual screenshots from HitPaw official website -->
### Image Enhancement Examples
| Before | After |
|--------|-------|
|  |  |
*Official HitPaw enhancement example (source: hitpaw.com)*
### Unblur / Sharpen Examples
| Before | After |
|--------|-------|
|  |  |
*Official HitPaw unblur example (source: hitpaw.com)*
### Video Enhancement Examples
| Original Frame | Enhanced Frame |
|----------------|----------------|
| Placeholder: add video frame comparison | Placeholder: add video frame comparison |
> **Note**: Video example placeholders. Replace with actual screenshots from HitPaw video enhancement results.
---
## 🎯 Feature Highlights
Based on official [HitPaw API Documentation](https://developer.hitpaw.com/image/Introduction):
- **Quality**: Industry-defining quality fit for professional use cases
- **Fidelity**: Preserves original details and identities
- **Efficiency**: Optimized for low latency and high throughput
### Supported Models
**Image Models** (16 total):
- General Enhance (2x/4x)
- Portrait Models (Clear/Natural)
- High Fidelity (2x/4x)
- Denoise & Sharpen models
- Generative Portrait & General
**Video Models**:
- Ultra HD Restore
- General Restore
- Portrait Restore
- Face Soft
- Generative Video
See [SKILL.md](SKILL.md) for complete model documentation and usage examples.
## 🚀 Quick Start
### Installation
```bash
clawhub install hitpaw-image-enhancer
```
### Configuration
Set your HitPaw API key:
```bash
export HITPAW_API_KEY="your_api_key_here"
```
Get your API key at: https://playground.hitpaw.com/
### Usage
```bash
# Enhance an image
enhance-image -u photo.jpg -m general_2x -o output.jpg
# Enhance a video
enhance-video -u input.mp4 -m general_restore_2x -r 1920x1080 -o output.mp4
```
## 📚 Documentation
For comprehensive documentation, including all model options, configuration details, and troubleshooting, see [SKILL.md](SKILL.md).
## 🔗 Links
- **ClawHub Skill**: https://clawhub.com/skill/hitpaw-image-enhancer
- **GitHub Repository**: https://github.com/HitPaw-Official/openclaw-skill-hitpaw-enhancer
- **HitPaw API Docs**: https://developer.hitpaw.com/
- **HitPaw Playground**: https://playground.hitpaw.com/
## 📄 License
MIT © HitPaw-Official
FILE:images/README.md
# Screenshots for HitPaw Skill
This folder should contain before/after comparison screenshots showcasing the HitPaw API enhancement capabilities.
## Recommended Screenshots
### Image Enhancement
- `image-before.jpg` - Original low-quality image sample
- `image-after.jpg` - Enhanced result using HitPaw API
### Video Enhancement
- `video-original.jpg` - Video frame before enhancement
- `video-enhanced.jpg` - Video frame after enhancement
### Model Comparisons (Optional)
- `face-clear.jpg` / `face-natural.jpg` - Portrait model comparison
- `general-upscale.jpg` - General upscaling example
- `generative-portrait.jpg` - Generative model output
## Sources for Screenshots
1. **HitPaw Playground**: https://playground.hitpaw.com/
- Upload test images and capture before/after
- Try different models and save comparison screenshots
2. **Official Documentation**:
- https://developer.hitpaw.com/image/available-models
- https://developer.hitpaw.com/video/available-models
- (Check for example images in the docs)
## Image Requirements
- Format: JPG or PNG
- Resolution: 800px+ width recommended
- Include watermarks or labels showing "Before" and "After"
- Compress for web (keep under 500KB each)
## Usage in Documentation
The README.md and SKILL.md reference these images using relative paths:
```markdown

```
Please add actual screenshot files before publishing the skill documentation publicly.
FILE:package-lock.json
{
"name": "openclaw-skill-hitpaw-enhancer",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openclaw-skill-hitpaw-enhancer",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"axios": "^1.6.0",
"chalk": "^5.3.0",
"commander": "^11.1.0",
"fs-extra": "^11.2.0",
"ora": "^8.0.1"
},
"bin": {
"enhance-image": "dist/cli.js",
"enhance-video": "dist/video-cli.js"
},
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"@types/node": "^20.0.0",
"typescript": "^5.3.0"
}
},
"node_modules/@types/fs-extra": {
"version": "11.0.4",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz",
"integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/jsonfile": "*",
"@types/node": "*"
}
},
"node_modules/@types/jsonfile": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz",
"integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "20.19.35",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.35.tgz",
"integrity": "sha512-Uarfe6J91b9HAUXxjvSOdiO2UPOKLm07Q1oh0JHxoZ1y8HoqxDAu3gVrsrOHeiio0kSsoVBt4wFrKOm0dKxVPQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
}
},
"node_modules/ansi-regex": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/axios": {
"version": "1.13.6",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz",
"integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/chalk": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/cli-cursor": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
"integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
"license": "MIT",
"dependencies": {
"restore-cursor": "^5.0.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/cli-spinners": {
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
"integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
"license": "MIT",
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"license": "MIT",
"engines": {
"node": ">=16"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/emoji-regex": {
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
"license": "MIT"
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/follow-redirects": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fs-extra": {
"version": "11.3.4",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz",
"integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==",
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
"node": ">=14.14"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-east-asian-width": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz",
"integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"license": "ISC"
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-interactive": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
"integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-unicode-supported": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
"integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/jsonfile": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
"license": "MIT",
"dependencies": {
"universalify": "^2.0.0"
},
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/log-symbols": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz",
"integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==",
"license": "MIT",
"dependencies": {
"chalk": "^5.3.0",
"is-unicode-supported": "^1.3.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/log-symbols/node_modules/is-unicode-supported": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz",
"integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mimic-function": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
"integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/onetime": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
"integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
"license": "MIT",
"dependencies": {
"mimic-function": "^5.0.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/ora": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz",
"integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==",
"license": "MIT",
"dependencies": {
"chalk": "^5.3.0",
"cli-cursor": "^5.0.0",
"cli-spinners": "^2.9.2",
"is-interactive": "^2.0.0",
"is-unicode-supported": "^2.0.0",
"log-symbols": "^6.0.0",
"stdin-discarder": "^0.2.2",
"string-width": "^7.2.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
"node_modules/restore-cursor": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
"integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
"license": "MIT",
"dependencies": {
"onetime": "^7.0.0",
"signal-exit": "^4.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"license": "ISC",
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/stdin-discarder": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz",
"integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/string-width": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"license": "MIT",
"dependencies": {
"emoji-regex": "^10.3.0",
"get-east-asian-width": "^1.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strip-ansi": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.2.2"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
"node_modules/universalify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
"license": "MIT",
"engines": {
"node": ">= 10.0.0"
}
}
}
}
FILE:package.json
{
"name": "openclaw-skill-hitpaw-enhancer",
"version": "1.0.3",
"description": "HitPaw Image & Video Enhancement Skill for OpenClaw",
"main": "dist/cli.js",
"type": "module",
"bin": {
"enhance-image": "./dist/cli.js",
"enhance-video": "./dist/video-cli.js"
},
"scripts": {
"build": "tsc && cp src/cli.js dist/ && cp src/video-cli.js dist/",
"prepublishOnly": "npm run build",
"start": "node dist/cli.js",
"start:video": "node dist/video-cli.js"
},
"keywords": [
"openclaw",
"skill",
"hitpaw",
"image",
"video",
"enhancement",
"upscale",
"ai"
],
"author": "Nova",
"license": "MIT",
"dependencies": {
"axios": "^1.6.0",
"chalk": "^5.3.0",
"commander": "^11.1.0",
"fs-extra": "^11.2.0",
"ora": "^8.0.1"
},
"devDependencies": {
"@types/node": "^20.0.0",
"@types/fs-extra": "^11.0.4",
"typescript": "^5.3.0"
}
}
FILE:src/cli.js
#!/usr/bin/env node
import { Command } from 'commander';
import chalk from 'chalk';
import ora from 'ora';
import path from 'path';
import fs from 'fs-extra';
import { HitPawClient } from './client.js';
const program = new Command();
program
.name('enhance-image')
.description('Enhance images using HitPaw AI API')
.version('1.0.0');
program
.option('-u, --url <url>', 'URL or local file path of the image')
.option('-o, --output <path>', 'Output file path', 'output.jpg')
.option('-m, --model <model>', 'Enhancement model', 'general_2x')
.option('-e, --extension <ext>', 'Output extension (e.g., .jpg, .png)', '.jpg')
.option('--dpi <number>', 'Target DPI for metadata')
.option('--keep-exif', 'Preserve EXIF data', false)
.option('--poll-interval <seconds>', 'Polling interval', '5')
.option('--timeout <seconds>', 'Max wait time', '300')
.requiredOption('-u, --url <url>', 'Image URL or local file path')
.action(async (options) => {
const apiKey = process.env.HITPAW_API_KEY;
if (!apiKey) {
console.error(chalk.red('Error: HITPAW_API_KEY environment variable is not set'));
console.log(chalk.yellow('Set it with: export HITPAW_API_KEY="your_key"'));
process.exit(1);
}
const { url, output, model, extension, dpi, keepExif, pollInterval, timeout } = options;
// Handle local file: need to convert to public URL (not supported in this skill)
// For now, only support URLs. For local files, user must upload somewhere first.
if (fs.existsSync(url)) {
console.error(chalk.red('Error: Local file paths are not directly supported.'));
console.log(chalk.yellow('Please upload the image to a public URL first, or use a service like transfer.sh'));
process.exit(1);
}
const client = new HitPawClient(apiKey);
const spinner = ora('Enhancing image...').start();
try {
const result = await client.enhanceAndDownload(url, output, {
model,
extension,
exif: keepExif,
dpi: dpi ? parseInt(dpi) : undefined,
pollInterval: parseInt(pollInterval),
timeout: parseInt(timeout)
});
spinner.succeed(chalk.green('Enhancement complete!'));
console.log(`Output: path.resolve(output)`);
console.log(`Coins consumed: result.coins`);
} catch (error) {
spinner.fail(chalk.red('Enhancement failed'));
console.error(chalk.red(error.message || 'Unknown error'));
// Parse error response
if (error.response?.data?.error_code) {
const code = error.response.data.error_code;
const messages = {
110400000: 'Invalid API key',
110402000: 'Insufficient coins',
110400005: 'Unsupported model',
110400007: 'Invalid extension',
100429000: 'Rate limit exceeded'
};
console.error(chalk.yellow(`Error code code: messages[code] || 'See documentation'`));
}
process.exit(1);
}
});
program.parse();
FILE:src/client.ts
import axios, { AxiosInstance } from 'axios';
import fs from 'fs-extra';
import path from 'path';
export interface EnhanceRequest {
model_name: string;
img_url: string;
extension: string;
exif?: boolean;
DPI?: number;
}
export interface VideoEnhanceRequest {
model_name: string;
video_url: string;
resolution: [number, number];
extension: string;
original_resolution?: [number, number];
}
export interface EnhanceResponse {
code: number;
message: string;
data: {
job_id: string;
consume_coins: number;
};
}
export interface StatusResponse {
code: number;
message: string;
data: {
job_id: string;
status: 'CONVERTING' | 'COMPLETED' | 'ERROR';
res_url?: string;
original_url?: string;
};
}
export class HitPawClient {
private client: AxiosInstance;
private apiKey: string;
private baseUrl: string;
constructor(apiKey: string, baseUrl = 'https://api-base.hitpaw.com') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
this.client = axios.create({
baseURL: baseUrl,
headers: {
'Content-Type': 'application/json',
'Apikey': apiKey
},
timeout: 60000
});
}
// === PHOTO ENHANCEMENT ===
async enhancePhoto(params: EnhanceRequest): Promise<EnhanceResponse> {
const response = await this.client.post('/api/photo-enhancer', params);
return response.data as EnhanceResponse;
}
// === VIDEO ENHANCEMENT ===
async enhanceVideo(params: VideoEnhanceRequest): Promise<EnhanceResponse> {
const response = await this.client.post('/api/video-enhancer', params);
return response.data as EnhanceResponse;
}
// === COMMON ===
async checkStatus(jobId: string): Promise<StatusResponse> {
const response = await this.client.post<StatusResponse>('/api/task-status', { job_id: jobId });
return response.data;
}
async waitForCompletion(jobId: string, maxAttempts = 360, pollInterval = 10): Promise<StatusResponse> {
let attempt = 0;
while (attempt < maxAttempts) {
const status = await this.checkStatus(jobId);
console.log(`[Attempt attempt + 1/maxAttempts] Status: status.data.status`);
if (status.data.status === 'COMPLETED') {
return status;
}
if (status.data.status === 'ERROR') {
throw new Error('Job failed with ERROR status');
}
await new Promise(resolve => setTimeout(resolve, pollInterval * 1000));
attempt++;
}
throw new Error(`Job did not complete within maxAttempts * pollInterval seconds`);
}
async downloadResult(url: string, outputPath: string): Promise<void> {
const response = await axios.get(url, { responseType: 'stream' });
await fs.ensureDir(path.dirname(outputPath));
response.data.pipe(fs.createWriteStream(outputPath));
await new Promise((resolve, reject) => {
response.data.on('end', resolve);
response.data.on('error', reject);
});
}
// === PHOTO HELPER ===
async enhanceAndDownload(
inputUrl: string,
outputPath: string,
options: {
model?: string;
extension?: string;
exif?: boolean;
dpi?: number;
pollInterval?: number;
timeout?: number;
} = {}
): Promise<{ coins: number }> {
const {
model = 'general_2x',
extension = '.jpg',
exif = true,
dpi,
pollInterval = 5,
timeout = 300
} = options;
console.log(`Submitting photo enhancement with model: model...`);
const enhanceResp = await this.enhancePhoto({
model_name: model,
img_url: inputUrl,
extension,
exif,
DPI: dpi
});
if (enhanceResp.code !== 200) {
throw new Error(`Enhance request failed: enhanceResp.message`);
}
console.log(`Job ID: enhanceResp.data.job_id`);
console.log(`Coins: enhanceResp.data.consume_coins`);
const status = await this.waitForCompletion(enhanceResp.data.job_id, Math.floor(timeout / pollInterval), pollInterval);
if (!status.data.res_url) {
throw new Error('No result URL in status response');
}
console.log(`Downloading to outputPath...`);
await this.downloadResult(status.data.res_url, outputPath);
console.log('✅ Photo enhancement complete!');
return { coins: enhanceResp.data.consume_coins };
}
// === VIDEO HELPER ===
async enhanceVideoAndDownload(
inputUrl: string,
outputPath: string,
options: {
model?: string;
resolution: [number, number];
original_resolution?: [number, number];
extension?: string;
pollInterval?: number;
timeout?: number;
}
): Promise<{ coins: number }> {
const DEFAULT_MODEL = 'general_restore_2x';
const DEFAULT_EXTENSION = '.mp4';
const {
model = DEFAULT_MODEL,
resolution,
extension = DEFAULT_EXTENSION,
original_resolution,
pollInterval = 10,
timeout = 600
} = options;
if (!resolution) {
throw new Error('resolution is required for video enhancement (e.g., [1920, 1080])');
}
console.log(`Submitting video enhancement with model: model...`);
console.log(`Target resolution: resolution[0]xresolution[1]`);
const requestBody: VideoEnhanceRequest = {
model_name: model,
video_url: inputUrl,
resolution,
extension
};
if (original_resolution) {
requestBody.original_resolution = original_resolution;
}
const enhanceResp = await this.enhanceVideo(requestBody);
if (enhanceResp.code !== 200) {
throw new Error(`Video enhance failed: enhanceResp.message`);
}
console.log(`Job ID: enhanceResp.data.job_id`);
console.log(`Coins: enhanceResp.data.consume_coins`);
const status = await this.waitForCompletion(enhanceResp.data.job_id, Math.floor(timeout / pollInterval), pollInterval);
if (!status.data.res_url) {
throw new Error('No result URL in status response');
}
console.log(`Downloading enhanced video to outputPath...`);
await this.downloadResult(status.data.res_url, outputPath);
console.log('✅ Video enhancement complete!');
return { coins: enhanceResp.data.consume_coins };
}
}
FILE:src/video-cli.js
#!/usr/bin/env node
import { Command } from 'commander';
import chalk from 'chalk';
import ora from 'ora';
import path from 'path';
import fs from 'fs-extra';
import { HitPawClient } from './client.js';
const program = new Command();
program
.name('enhance-video')
.description('Enhance videos using HitPaw AI Video Enhancement API')
.version('1.0.0');
program
.option('-u, --url <url>', 'URL or local file path of the video')
.option('-o, --output <path>', 'Output file path', 'output.mp4')
.option('-m, --model <model>', 'Enhancement model (see models table below)', 'general_restore_2x')
.option('-r, --resolution <wxh>', 'Target resolution (required, e.g., 1920x1080)')
.option('-e, --extension <ext>', 'Output extension (e.g., .mp4, .mov, .avi)', '.mp4')
.option('--original-resolution <wxh>', 'Original video resolution (optional, e.g., 1280x720)')
.option('--poll-interval <seconds>', 'Polling interval (default 10s for video)', '10')
.option('--timeout <seconds>', 'Max wait time (default 600s for video)', '600')
.requiredOption('-u, --url <url>', 'Video URL or local file path')
.action(async (options) => {
const apiKey = process.env.HITPAW_API_KEY;
if (!apiKey) {
console.error(chalk.red('Error: HITPAW_API_KEY environment variable is not set'));
console.log(chalk.yellow('Set it with: export HITPAW_API_KEY="your_key"'));
process.exit(1);
}
const { url, output, model, resolution, extension, original_resolution, pollInterval, timeout } = options;
// Parse resolution strings
<<<<<<< HEAD
const parseRes = (str: string): [number, number] => {
=======
const parseRes = (str) => {
>>>>>>> 96b5b31 (docs: 丰富 HitPaw API 功能文档)
const [w, h] = str.split('x').map(Number);
if (!w || !h) throw new Error(`Invalid resolution format: str. Use WxH (e.g., 1920x1080)`);
return [w, h];
};
if (!resolution) {
console.error(chalk.red('Error: --resolution (-r) is required for video enhancement'));
console.log(chalk.yellow('Example: -r 1920x1080'));
process.exit(1);
}
const targetRes = parseRes(resolution);
const originalRes = original_resolution ? parseRes(original_resolution) : undefined;
if (fs.existsSync(url)) {
console.error(chalk.red('Error: Local file paths are not directly supported.'));
console.log(chalk.yellow('Please upload the video to a public URL first.'));
process.exit(1);
}
const client = new HitPawClient(apiKey);
const spinner = ora('Enhancing video...').start();
try {
const result = await client.enhanceVideoAndDownload(url, output, {
model,
resolution: targetRes,
extension,
original_resolution: originalRes,
pollInterval: parseInt(pollInterval),
timeout: parseInt(timeout)
});
spinner.succeed(chalk.green('Video enhancement complete!'));
console.log(`Output: path.resolve(output)`);
console.log(`Coins consumed: result.coins`);
<<<<<<< HEAD
} catch (error: any) {
=======
} catch (error) {
>>>>>>> 96b5b31 (docs: 丰富 HitPaw API 功能文档)
spinner.fail(chalk.red('Video enhancement failed'));
console.error(chalk.red(error.message || 'Unknown error'));
if (error.response?.data?.error_code) {
const code = error.response.data.error_code;
<<<<<<< HEAD
const messages: Record<number, string> = {
=======
const messages = {
>>>>>>> 96b5b31 (docs: 丰富 HitPaw API 功能文档)
110400000: 'Invalid API key',
110402000: 'Insufficient coins',
110400005: 'Unsupported model',
110400007: 'Invalid extension',
110400008: 'Invalid video URL',
110400009: 'Input resolution over limit',
110400010: 'Target resolution over limit',
110400011: 'Video duration over limit',
100429000: 'Rate limit exceeded'
};
console.error(chalk.yellow(`Error code code: messages[code] || 'See documentation'`));
}
process.exit(1);
}
});
program.parse();
FILE:tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": false,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}