Add AppImage packaging, app icon, and AppStream metainfo

This commit is contained in:
2026-03-06 18:31:18 +02:00
parent 704f556867
commit 4f23d25511
4 changed files with 222 additions and 0 deletions

105
build-appimage.sh Normal file
View File

@@ -0,0 +1,105 @@
#!/bin/bash
set -euo pipefail
# Build Pixstrip AppImage
# Requires: cargo, linuxdeploy (with gtk plugin), appimagetool
# Usage: ./build-appimage.sh [--release]
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
BUILD_TYPE="release"
CARGO_FLAGS="--release"
if [[ "${1:-}" == "--debug" ]]; then
BUILD_TYPE="debug"
CARGO_FLAGS=""
fi
APP_ID="live.lashman.Pixstrip"
APP_DIR="$SCRIPT_DIR/AppDir"
TOOLS_DIR="$SCRIPT_DIR/build-tools"
echo "=== Building Pixstrip AppImage ($BUILD_TYPE) ==="
# Step 1: Build binaries
echo "--- Building binaries ---"
cargo build $CARGO_FLAGS --workspace
# Step 2: Create AppDir structure
echo "--- Creating AppDir ---"
rm -rf "$APP_DIR"
mkdir -p "$APP_DIR/usr/bin"
mkdir -p "$APP_DIR/usr/share/applications"
mkdir -p "$APP_DIR/usr/share/icons/hicolor/scalable/apps"
mkdir -p "$APP_DIR/usr/share/metainfo"
# Step 3: Copy binaries
cp "target/$BUILD_TYPE/pixstrip-gtk" "$APP_DIR/usr/bin/pixstrip-gtk"
cp "target/$BUILD_TYPE/pixstrip-cli" "$APP_DIR/usr/bin/pixstrip"
# Step 4: Copy desktop file, icon, metainfo
cp "data/$APP_ID.desktop" "$APP_DIR/usr/share/applications/"
cp "data/icons/hicolor/scalable/apps/$APP_ID.svg" "$APP_DIR/usr/share/icons/hicolor/scalable/apps/"
cp "data/$APP_ID.metainfo.xml" "$APP_DIR/usr/share/metainfo/"
# Symlinks required by AppImage spec
ln -sf "usr/share/applications/$APP_ID.desktop" "$APP_DIR/$APP_ID.desktop"
ln -sf "usr/share/icons/hicolor/scalable/apps/$APP_ID.svg" "$APP_DIR/$APP_ID.svg"
# Step 5: Create AppRun
cat > "$APP_DIR/AppRun" << 'APPRUN'
#!/bin/bash
SELF="$(readlink -f "$0")"
HERE="${SELF%/*}"
export PATH="${HERE}/usr/bin:${PATH}"
export LD_LIBRARY_PATH="${HERE}/usr/lib:${HERE}/usr/lib/x86_64-linux-gnu:${LD_LIBRARY_PATH:-}"
export XDG_DATA_DIRS="${HERE}/usr/share:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
export GI_TYPELIB_PATH="${HERE}/usr/lib/x86_64-linux-gnu/girepository-1.0:${GI_TYPELIB_PATH:-}"
exec "${HERE}/usr/bin/pixstrip-gtk" "$@"
APPRUN
chmod +x "$APP_DIR/AppRun"
# Step 6: Bundle shared libraries
echo "--- Bundling libraries ---"
mkdir -p "$TOOLS_DIR"
# Download linuxdeploy if not present
if [[ ! -x "$TOOLS_DIR/linuxdeploy" ]]; then
echo "Downloading linuxdeploy..."
wget -q -O "$TOOLS_DIR/linuxdeploy" \
"https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
chmod +x "$TOOLS_DIR/linuxdeploy"
fi
# Download linuxdeploy GTK plugin if not present
if [[ ! -x "$TOOLS_DIR/linuxdeploy-plugin-gtk.sh" ]]; then
echo "Downloading linuxdeploy GTK plugin..."
wget -q -O "$TOOLS_DIR/linuxdeploy-plugin-gtk.sh" \
"https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh"
chmod +x "$TOOLS_DIR/linuxdeploy-plugin-gtk.sh"
fi
# Use linuxdeploy to bundle dependencies
export DEPLOY_GTK_VERSION=4
"$TOOLS_DIR/linuxdeploy" \
--appdir "$APP_DIR" \
--desktop-file "$APP_DIR/usr/share/applications/$APP_ID.desktop" \
--icon-file "$APP_DIR/usr/share/icons/hicolor/scalable/apps/$APP_ID.svg" \
--plugin gtk
# Step 7: Build the AppImage
echo "--- Creating AppImage ---"
# Download appimagetool if not present
if [[ ! -x "$TOOLS_DIR/appimagetool" ]]; then
echo "Downloading appimagetool..."
wget -q -O "$TOOLS_DIR/appimagetool" \
"https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod +x "$TOOLS_DIR/appimagetool"
fi
VERSION="0.1.0"
"$TOOLS_DIR/appimagetool" "$APP_DIR" "Pixstrip-${VERSION}-x86_64.AppImage"
echo ""
echo "=== AppImage built: Pixstrip-${VERSION}-x86_64.AppImage ==="
echo "Size: $(du -h "Pixstrip-${VERSION}-x86_64.AppImage" | cut -f1)"

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" width="128" height="128">
<!-- Pixstrip app icon: scissors cutting a film strip / image strip -->
<!-- Film strip background -->
<rect x="16" y="32" width="96" height="64" rx="6" ry="6" fill="#3584e4" opacity="0.9"/>
<!-- Film strip sprocket holes - top -->
<rect x="24" y="36" width="8" height="8" rx="2" fill="#fff" opacity="0.5"/>
<rect x="40" y="36" width="8" height="8" rx="2" fill="#fff" opacity="0.5"/>
<rect x="56" y="36" width="8" height="8" rx="2" fill="#fff" opacity="0.5"/>
<rect x="72" y="36" width="8" height="8" rx="2" fill="#fff" opacity="0.5"/>
<rect x="88" y="36" width="8" height="8" rx="2" fill="#fff" opacity="0.5"/>
<!-- Film strip sprocket holes - bottom -->
<rect x="24" y="84" width="8" height="8" rx="2" fill="#fff" opacity="0.5"/>
<rect x="40" y="84" width="8" height="8" rx="2" fill="#fff" opacity="0.5"/>
<rect x="56" y="84" width="8" height="8" rx="2" fill="#fff" opacity="0.5"/>
<rect x="72" y="84" width="8" height="8" rx="2" fill="#fff" opacity="0.5"/>
<rect x="88" y="84" width="8" height="8" rx="2" fill="#fff" opacity="0.5"/>
<!-- Image frames in the strip -->
<rect x="24" y="48" width="20" height="32" rx="2" fill="#fff" opacity="0.85"/>
<rect x="48" y="48" width="20" height="32" rx="2" fill="#fff" opacity="0.85"/>
<rect x="72" y="48" width="20" height="32" rx="2" fill="#fff" opacity="0.85"/>
<!-- Mini landscape icons inside frames -->
<circle cx="30" cy="56" r="3" fill="#77767b" opacity="0.6"/>
<polygon points="26,74 34,66 38,70 42,64 44,74" fill="#77767b" opacity="0.4"/>
<circle cx="54" cy="56" r="3" fill="#77767b" opacity="0.6"/>
<polygon points="50,74 58,66 62,70 66,64 68,74" fill="#77767b" opacity="0.4"/>
<circle cx="78" cy="56" r="3" fill="#77767b" opacity="0.6"/>
<polygon points="74,74 82,66 86,70 90,64 92,74" fill="#77767b" opacity="0.4"/>
<!-- Scissors - cutting diagonally across the strip -->
<!-- Scissor blade 1 (top-right) -->
<path d="M98,20 L70,58 L74,62 L102,24 Z" fill="#e01b24" opacity="0.9"/>
<circle cx="100" cy="18" r="8" fill="none" stroke="#e01b24" stroke-width="3" opacity="0.9"/>
<circle cx="100" cy="18" r="3" fill="#e01b24" opacity="0.5"/>
<!-- Scissor blade 2 (bottom-right) -->
<path d="M98,108 L70,70 L74,66 L102,104 Z" fill="#e01b24" opacity="0.9"/>
<circle cx="100" cy="110" r="8" fill="none" stroke="#e01b24" stroke-width="3" opacity="0.9"/>
<circle cx="100" cy="110" r="3" fill="#e01b24" opacity="0.5"/>
<!-- Scissor pivot -->
<circle cx="74" cy="64" r="3" fill="#a51d2d"/>
<!-- Cut line (dashed) -->
<line x1="74" y1="64" x2="16" y2="64" stroke="#a51d2d" stroke-width="1.5" stroke-dasharray="4,3" opacity="0.7"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>live.lashman.Pixstrip</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>CC0-1.0</project_license>
<name>Pixstrip</name>
<summary>Batch image processor - resize, convert, compress, and more</summary>
<description>
<p>
Pixstrip is a batch image processor for Linux that combines resize, convert,
compress, metadata strip, watermark, rename, and basic image adjustments into
a single wizard-driven workflow.
</p>
<p>Features include:</p>
<ul>
<li>Resize images by width, height, fit-in-box, or social media presets</li>
<li>Convert between JPEG, PNG, WebP, AVIF, GIF, and TIFF</li>
<li>Compress with optimized encoders (mozjpeg, oxipng, libwebp, ravif)</li>
<li>Strip or selectively manage EXIF metadata for privacy</li>
<li>Add text or image watermarks with positioning and rotation</li>
<li>Rename files with templates, counters, regex, and EXIF variables</li>
<li>Adjust brightness, contrast, saturation, and apply effects</li>
<li>Built-in presets for common workflows</li>
<li>Watch folders for automatic processing</li>
<li>Full CLI with feature parity</li>
</ul>
</description>
<launchable type="desktop-id">live.lashman.Pixstrip.desktop</launchable>
<url type="homepage">https://git.lashman.live/lashman/pixstrip</url>
<url type="bugtracker">https://git.lashman.live/lashman/pixstrip/issues</url>
<developer id="live.lashman">
<name>lashman</name>
</developer>
<branding>
<color type="primary" scheme_preference="light">#99c1f1</color>
<color type="primary" scheme_preference="dark">#1a5fb4</color>
</branding>
<content_rating type="oars-1.1" />
<requires>
<display_length compare="ge">360</display_length>
</requires>
<supports>
<control>pointing</control>
<control>keyboard</control>
<control>touch</control>
</supports>
<releases>
<release version="0.1.0" date="2026-03-06">
<description>
<p>Initial release with full wizard workflow, 8 built-in presets, CLI parity, watch folders, and file manager integration.</p>
</description>
</release>
</releases>
</component>

View File

@@ -555,6 +555,7 @@ fn build_ui(app: &adw::Application) {
.default_height(win_height)
.content(&toast_overlay)
.title("Pixstrip")
.icon_name(APP_ID)
.build();
if session_state.window_maximized {