develop #1

Open
maddo wants to merge 126 commits from develop into master
345 changed files with 16644 additions and 99279 deletions

View file

@ -0,0 +1,206 @@
name: Build Catalog Lite
on:
workflow_dispatch:
inputs:
expiration_date:
description: Catalog Lite expiration date, yyyy-MM-dd
required: true
default: '2026-12-31'
type: string
env:
DOTNET_VERSION: 10.0.x
PROJECT_PATH: CatalogLite/CatalogLite.csproj
CATALOG_LITE_EXPIRATION_DATE: ${{ inputs.expiration_date }}
jobs:
build:
runs-on: docker
strategy:
fail-fast: false
matrix:
include:
- runtime: win-x64
artifact_name: catalog-lite-win-x64
executable_name: CatalogLite.exe
- runtime: linux-x64
artifact_name: catalog-lite-linux-x64
executable_name: CatalogLite
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Validate expiration date
run: |
set -eu
case "${CATALOG_LITE_EXPIRATION_DATE}" in
????-??-??) ;;
*)
echo "expiration_date must use yyyy-MM-dd format"
exit 1
;;
esac
- name: Restore
run: dotnet restore "${{ env.PROJECT_PATH }}" -r "${{ matrix.runtime }}" --configfile NuGet.Config
- name: Publish Catalog Lite
env:
PUBLISH_DIR: artifacts/publish/${{ matrix.runtime }}
run: |
set -eu
dotnet publish "${{ env.PROJECT_PATH }}" \
-c Release \
-r "${{ matrix.runtime }}" \
--self-contained false \
--no-restore \
-p:CatalogLiteExpirationDate="${CATALOG_LITE_EXPIRATION_DATE}" \
-p:PublishSingleFile=true \
-p:SelfContained=false \
-p:IncludeNativeLibrariesForSelfExtract=true \
-p:PublishTrimmed=false \
-p:PublishReadyToRun=false \
-p:DebugType=embedded \
-o "${PUBLISH_DIR}"
- name: Validate published files
env:
PUBLISH_DIR: artifacts/publish/${{ matrix.runtime }}
run: |
set -eu
executable="${PUBLISH_DIR}/${{ matrix.executable_name }}"
if [ ! -f "${executable}" ]; then
echo "Catalog Lite executable was not produced: ${executable}"
exit 1
fi
loose_library_count="$(find "${PUBLISH_DIR}" -maxdepth 1 -type f \( -iname '*.dll' -o -name '*.so' -o -name '*.dylib' \) | wc -l | tr -d ' ')"
if [ "${loose_library_count}" -ne 0 ]; then
echo "Catalog Lite publish must not contain loose native or managed libraries:"
find "${PUBLISH_DIR}" -maxdepth 1 -type f \( -iname '*.dll' -o -name '*.so' -o -name '*.dylib' \) -print
exit 1
fi
extra_file_count="$(find "${PUBLISH_DIR}" -maxdepth 1 -type f ! -name "${{ matrix.executable_name }}" | wc -l | tr -d ' ')"
if [ "${extra_file_count}" -ne 0 ]; then
echo "Catalog Lite publish artifact must contain only ${{ matrix.executable_name }}:"
find "${PUBLISH_DIR}" -maxdepth 1 -type f ! -name "${{ matrix.executable_name }}" -print
exit 1
fi
- name: Upload publish artifact
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.artifact_name }}
path: artifacts/publish/${{ matrix.runtime }}/${{ matrix.executable_name }}
if-no-files-found: error
release:
needs: build
runs-on: docker
env:
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
steps:
- name: Download Windows artifact
uses: actions/download-artifact@v3
with:
name: catalog-lite-win-x64
path: artifacts/release/win-x64
- name: Validate release token
run: |
set -eu
if [ -z "${FORGEJO_TOKEN}" ]; then
echo "secrets.FORGEJO_TOKEN is required for Catalog Lite releases"
exit 1
fi
- name: Create or update release
run: |
set -eu
api_base="${FORGEJO_SERVER_URL%/}/api/v1/repos/${FORGEJO_REPOSITORY}"
tag="catalog-lite-${CATALOG_LITE_EXPIRATION_DATE}"
name="Catalog Lite ${CATALOG_LITE_EXPIRATION_DATE}"
commit="${FORGEJO_SHA:-${GITHUB_SHA:-}}"
create_payload="$(printf '{"tag_name":"%s","target_commitish":"%s","name":"%s","body":"Catalog Lite\\n\\nScadenza build: %s","draft":false,"prerelease":false}' "${tag}" "${commit}" "${name}" "${CATALOG_LITE_EXPIRATION_DATE}")"
update_payload="$(printf '{"body":"Catalog Lite\\n\\nScadenza build: %s"}' "${CATALOG_LITE_EXPIRATION_DATE}")"
http_code="$(curl -sS -o release.json -w '%{http_code}' \
-H "Authorization: token ${FORGEJO_TOKEN}" \
"${api_base}/releases/tags/${tag}")"
if [ "${http_code}" = "200" ]; then
release_id="$(sed -n 's/.*"id":\([0-9][0-9]*\).*/\1/p' release.json | head -n1)"
curl -fsS \
-H "Authorization: token ${FORGEJO_TOKEN}" \
-H "Content-Type: application/json" \
-X PATCH \
-d "${update_payload}" \
"${api_base}/releases/${release_id}" \
-o release.json
elif [ "${http_code}" = "404" ]; then
curl -fsS \
-H "Authorization: token ${FORGEJO_TOKEN}" \
-H "Content-Type: application/json" \
-X POST \
-d "${create_payload}" \
"${api_base}/releases" \
-o release.json
release_id="$(sed -n 's/.*"id":\([0-9][0-9]*\).*/\1/p' release.json | head -n1)"
else
echo "Unexpected response while loading release for tag ${tag}: ${http_code}"
cat release.json
exit 1
fi
if [ -z "${release_id}" ]; then
echo "Unable to resolve Forgejo release id"
cat release.json
exit 1
fi
echo "RELEASE_ID=${release_id}" >> "${GITHUB_ENV}"
- name: Upload release assets
run: |
set -eu
api_base="${FORGEJO_SERVER_URL%/}/api/v1/repos/${FORGEJO_REPOSITORY}"
windows_exe="$(find artifacts/release/win-x64 -maxdepth 1 -type f -iname '*.exe' | head -n1)"
if [ -z "${windows_exe}" ]; then
echo "No Windows executable found in downloaded artifact"
exit 1
fi
curl -fsS \
-H "Authorization: token ${FORGEJO_TOKEN}" \
"${api_base}/releases/${RELEASE_ID}/assets" \
-o assets.json
for asset_id in $(tr '{' '\n' < assets.json | sed -n 's/.*"id":\([0-9][0-9]*\).*"name":"[^"]*".*/\1/p'); do
curl -fsS \
-H "Authorization: token ${FORGEJO_TOKEN}" \
-X DELETE \
"${api_base}/releases/${RELEASE_ID}/assets/${asset_id}"
done
upload_asset() {
asset_path="$1"
asset_name="$2"
curl -fsS \
-H "Authorization: token ${FORGEJO_TOKEN}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"${asset_path}" \
"${api_base}/releases/${RELEASE_ID}/assets?name=${asset_name}"
}
upload_asset "${windows_exe}" "CatalogLite-${CATALOG_LITE_EXPIRATION_DATE}.exe"

View file

@ -0,0 +1,107 @@
name: Build Windows Avalonia
on:
push:
branches:
- master
- develop
paths:
- '.forgejo/workflows/build-windows-avalonia.yml'
- 'Catalog.Communication/**'
- 'GitVersion.yml'
- 'NuGet.Config'
- 'MaddoShared/**'
- 'imagecatalog/**'
workflow_dispatch:
env:
DOTNET_VERSION: 10.0.x
PROJECT_PATH: imagecatalog/ImageCatalog 2.csproj
PUBLISH_DIR: artifacts/publish/win-x64
ARTIFACT_NAME: imagecatalog-windows-avalonia
NUGET_SOURCE_NAME: Nuget-Forgejo-AIFotoONLUS
NUGET_SOURCE_URL: ${{ vars.AIFOTOONLUS_NUGET_SOURCE_URL || format('{0}/api/packages/{1}/nuget/index.json', github.server_url, vars.AIFOTOONLUS_PACKAGE_OWNER || github.repository_owner) }}
jobs:
build:
runs-on: docker
env:
FORGEJO_PACKAGE_USERNAME: ${{ secrets.FORGEJO_PACKAGE_USERNAME }}
FORGEJO_PACKAGE_TOKEN: ${{ secrets.FORGEJO_PACKAGE_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Validate NuGet secrets
run: |
set -eu
if [ -z "${FORGEJO_PACKAGE_USERNAME}" ]; then
echo "secrets.FORGEJO_PACKAGE_USERNAME is required"
exit 1
fi
if [ -z "${FORGEJO_PACKAGE_TOKEN}" ]; then
echo "secrets.FORGEJO_PACKAGE_TOKEN is required"
exit 1
fi
- name: Configure private NuGet source
run: |
set -eu
temp_config="${RUNNER_TEMP}/nuget.config"
cp NuGet.Config "${temp_config}"
dotnet nuget update source "${{ env.NUGET_SOURCE_NAME }}" \
--source "${{ env.NUGET_SOURCE_URL }}" \
--username "${FORGEJO_PACKAGE_USERNAME}" \
--password "${FORGEJO_PACKAGE_TOKEN}" \
--store-password-in-clear-text \
--configfile "${temp_config}"
echo "NUGET_CONFIG_PATH=${temp_config}" >> "${GITHUB_ENV}"
- name: Restore
run: dotnet restore "${{ env.PROJECT_PATH }}" -r win-x64 --configfile "${NUGET_CONFIG_PATH}"
- name: Publish Windows Avalonia build
run: |
set -eu
dotnet publish "${{ env.PROJECT_PATH }}" \
-c Release \
-r win-x64 \
--self-contained true \
--no-restore \
-p:AvaloniaWindowsCrossPublish=true \
-p:PublishSingleFile=true \
-p:PublishTrimmed=false \
-p:PublishReadyToRun=false \
-o "${{ env.PUBLISH_DIR }}"
- name: Validate published executable
run: |
set -eu
exe_count="$(find "${{ env.PUBLISH_DIR }}" -maxdepth 1 -type f -iname '*.exe' | wc -l | tr -d ' ')"
if [ "${exe_count}" -eq 0 ]; then
echo "No Windows executable produced in ${{ env.PUBLISH_DIR }}"
exit 1
fi
legacy_renderer_count="$(find "${{ env.PUBLISH_DIR }}" -maxdepth 1 -type f \( -iname 'Microsoft.Windows.Compatibility.dll' -o -iname 'System.Private.Windows.GdiPlus.dll' \) | wc -l | tr -d ' ')"
if [ "${legacy_renderer_count}" -ne 0 ]; then
echo "Legacy GDI compatibility assemblies must not be published:"
find "${{ env.PUBLISH_DIR }}" -maxdepth 1 -type f \( -iname 'Microsoft.Windows.Compatibility.dll' -o -iname 'System.Private.Windows.GdiPlus.dll' \) -print
exit 1
fi
- name: Upload publish artifact
uses: actions/upload-artifact@v3
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.PUBLISH_DIR }}
if-no-files-found: error

View file

@ -0,0 +1,174 @@
name: Release Windows Avalonia
on:
push:
tags:
- '*'
env:
DOTNET_VERSION: 10.0.x
PROJECT_PATH: imagecatalog/ImageCatalog 2.csproj
PUBLISH_DIR: artifacts/publish/win-x64
ARTIFACT_NAME: imagecatalog-windows-avalonia
NUGET_SOURCE_NAME: Nuget-Forgejo-AIFotoONLUS
NUGET_SOURCE_URL: ${{ vars.AIFOTOONLUS_NUGET_SOURCE_URL || format('{0}/api/packages/{1}/nuget/index.json', forgejo.server_url, vars.AIFOTOONLUS_PACKAGE_OWNER || forgejo.repository_owner) }}
jobs:
build:
runs-on: docker
env:
FORGEJO_PACKAGE_USERNAME: ${{ secrets.FORGEJO_PACKAGE_USERNAME }}
FORGEJO_PACKAGE_TOKEN: ${{ secrets.FORGEJO_PACKAGE_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Validate NuGet secrets
run: |
set -eu
if [ -z "${FORGEJO_PACKAGE_USERNAME}" ]; then
echo "secrets.FORGEJO_PACKAGE_USERNAME is required"
exit 1
fi
if [ -z "${FORGEJO_PACKAGE_TOKEN}" ]; then
echo "secrets.FORGEJO_PACKAGE_TOKEN is required"
exit 1
fi
- name: Configure private NuGet source
run: |
set -eu
temp_config="${RUNNER_TEMP}/nuget.config"
cp NuGet.Config "${temp_config}"
dotnet nuget update source "${{ env.NUGET_SOURCE_NAME }}" \
--source "${{ env.NUGET_SOURCE_URL }}" \
--username "${FORGEJO_PACKAGE_USERNAME}" \
--password "${FORGEJO_PACKAGE_TOKEN}" \
--store-password-in-clear-text \
--configfile "${temp_config}"
echo "NUGET_CONFIG_PATH=${temp_config}" >> "${GITHUB_ENV}"
- name: Restore
run: dotnet restore "${{ env.PROJECT_PATH }}" -r win-x64 --configfile "${NUGET_CONFIG_PATH}"
- name: Publish Windows Avalonia build
run: |
set -eu
dotnet publish "${{ env.PROJECT_PATH }}" \
-c Release \
-r win-x64 \
--self-contained true \
--no-restore \
-p:AvaloniaWindowsCrossPublish=true \
-p:PublishSingleFile=true \
-p:PublishTrimmed=false \
-p:PublishReadyToRun=false \
-o "${{ env.PUBLISH_DIR }}"
- name: Validate published executable
run: |
set -eu
exe_count="$(find "${{ env.PUBLISH_DIR }}" -maxdepth 1 -type f -iname '*.exe' | wc -l | tr -d ' ')"
if [ "${exe_count}" -eq 0 ]; then
echo "No Windows executable produced in ${{ env.PUBLISH_DIR }}"
exit 1
fi
legacy_renderer_count="$(find "${{ env.PUBLISH_DIR }}" -maxdepth 1 -type f \( -iname 'Microsoft.Windows.Compatibility.dll' -o -iname 'System.Private.Windows.GdiPlus.dll' \) | wc -l | tr -d ' ')"
if [ "${legacy_renderer_count}" -ne 0 ]; then
echo "Legacy GDI compatibility assemblies must not be published:"
find "${{ env.PUBLISH_DIR }}" -maxdepth 1 -type f \( -iname 'Microsoft.Windows.Compatibility.dll' -o -iname 'System.Private.Windows.GdiPlus.dll' \) -print
exit 1
fi
- name: Upload publish artifact
uses: actions/upload-artifact@v3
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.PUBLISH_DIR }}
if-no-files-found: error
release:
needs: build
runs-on: docker
env:
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
steps:
- name: Download publish artifact
uses: actions/download-artifact@v3
with:
name: ${{ env.ARTIFACT_NAME }}
path: artifacts/release
- name: Validate release token
run: |
set -eu
if [ -z "${FORGEJO_TOKEN}" ]; then
echo "secrets.FORGEJO_TOKEN is required for tagged releases"
exit 1
fi
- name: Create or reuse release
run: |
set -eu
api_base="${FORGEJO_SERVER_URL%/}/api/v1/repos/${FORGEJO_REPOSITORY}"
tag="${FORGEJO_REF_NAME}"
http_code="$(curl -sS -o release.json -w '%{http_code}' \
-H "Authorization: token ${FORGEJO_TOKEN}" \
"${api_base}/releases/tags/${tag}")"
if [ "${http_code}" = "200" ]; then
release_id="$(sed -n 's/.*"id":\([0-9][0-9]*\).*/\1/p' release.json | head -n1)"
elif [ "${http_code}" = "404" ]; then
payload="$(printf '{"tag_name":"%s","name":"%s","draft":false,"prerelease":false}' "${tag}" "${tag}")"
curl -fsS \
-H "Authorization: token ${FORGEJO_TOKEN}" \
-H "Content-Type: application/json" \
-X POST \
-d "${payload}" \
"${api_base}/releases" \
-o release.json
release_id="$(sed -n 's/.*"id":\([0-9][0-9]*\).*/\1/p' release.json | head -n1)"
else
echo "Unexpected response while loading release for tag ${tag}: ${http_code}"
cat release.json
exit 1
fi
if [ -z "${release_id}" ]; then
echo "Unable to resolve Forgejo release id"
cat release.json
exit 1
fi
echo "RELEASE_ID=${release_id}" >> "${GITHUB_ENV}"
- name: Upload executable to release
run: |
set -eu
api_base="${FORGEJO_SERVER_URL%/}/api/v1/repos/${FORGEJO_REPOSITORY}"
executable_path="$(find artifacts/release -maxdepth 1 -type f -iname '*.exe' | head -n1)"
if [ -z "${executable_path}" ]; then
echo "No executable found in downloaded artifact"
exit 1
fi
short_sha="$(printf '%s' "${FORGEJO_SHA}" | cut -c1-12)"
asset_name="ImageCatalog-avalonia-win-x64-${FORGEJO_REF_NAME}-${short_sha}.exe"
curl -fsS \
-H "Authorization: token ${FORGEJO_TOKEN}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"${executable_path}" \
"${api_base}/releases/${RELEASE_ID}/assets?name=${asset_name}"

81
.github/copilot-instructions.md vendored Normal file
View file

@ -0,0 +1,81 @@
# Copilot Instructions
## Build & Test Commands
```powershell
# Build
dotnet build Catalog.slnx
# Run all tests
dotnet test MaddoShared.Tests
# Run a single test
dotnet test MaddoShared.Tests --filter "FullyQualifiedName~MethodName"
# Benchmarks (modes: quick | all | parallel | chunks | sizes | stress)
.\run-benchmarks.ps1 quick
# Publish release build (self-contained Windows EXE)
dotnet publish "imagecatalog\ImageCatalog 2.csproj" -c Release -r win-x64 --self-contained
```
## Architecture
This is an Avalonia image cataloging application targeting .NET 10.0-windows.
### Projects
| Project | Purpose |
|---------|---------|
| **imagecatalog** | Main desktop application — Avalonia with Fluent theme (`AvaloniaMainWindow`) |
| **MaddoShared** | Shared image processing library (the core) |
| **MaddoShared.Tests** | Unit tests for MaddoShared |
| **MaddoShared.Benchmarks** | BenchmarkDotNet performance benchmarks |
| **WPFCatalog** | Alternate WPF UI (secondary) |
| **ImageCatalogCS / ImageCatalogParallel** | Legacy/experimental variants |
| **CatalogLib / CatalogLibVb / CatalogVbLib** | Legacy VB.NET libraries |
The main app launches Avalonia directly. Dialog events (`SelectSourceFolderRequested`, etc.) are subscribed in `AvaloniaMainWindow` code-behind. `DataModel.UiInvoker` must be set by the active UI to enable cross-thread UI updates (Avalonia sets this to `Dispatcher.UIThread.Invoke`).
### Core Flow
1. User configures paths/settings in the UI (`DataModel.cs` — MVVM ViewModel)
2. `ProcessImagesCommand` triggers `ImageCreationService`
3. `ImageCreationService` processes files in parallel chunks, with configurable concurrency and batch size (GC flush between chunks)
4. Each file is handled by the ImageSharp `IImageCreator` implementation
5. Output: resized/watermarked/overlaid images written to a destination folder hierarchy
### Key Abstractions (MaddoShared)
- **`IImageCreator`** — single async method to process one image; implemented by `ImageCreatorImageSharp` (SixLabors.ImageSharp)
- **`ImageCreationService`** — parallel orchestrator; uses `AsyncEnumerator` with chunking; loads logo once, clones per thread for thread safety
- **`ImageState`** — per-file processing context (input path, EXIF orientation, thumbnail sizes, overlays, logo, rotation)
- **`PicSettings`** — 50+ property configuration model (dimensions, fonts, colors, JPEG quality, watermark, logo positioning)
- **`FileHelperSharp`** — recursive file enumeration with folder-per-N-files mapping and counter formatting
## Conventions
### C# Style
- File-scoped namespaces everywhere: `namespace MaddoShared;`
- Nullable reference types enabled (`<Nullable>enable</Nullable>`)
- Implicit usings enabled
- `ConfigureAwait(false)` on all `await` calls in library code
### Dependency Injection
- Constructor injection throughout; loggers typed as `ILogger<T>`
- Main app wires services in `Program.cs` via `IServiceCollection`
### Testing
- MSTest with `[TestClass]` / `[TestMethod]`
- FluentAssertions for assertions
- Moq for mocking
- Factory helper pattern in tests: `CreateService(Action<Config> configure = null)` methods for flexible test setup
### Async / Parallelism
- All image I/O is `async Task`
- `ImageCreationService` uses configurable `MaxDegreeOfParallelism` and `ChunkSize`; explicit `GC.Collect()` between chunks to manage memory under batch load
### Versioning & CI
- Semantic versioning via **GitVersion** (mode: `ContinuousDelivery`, current base: `3.2.0`)
- GitLab CI pipeline: builds → single-file self-contained EXE → GitLab Release
- Private NuGet packages scoped to `AIFotoONLUS.*` prefix, routed to the GitLab package registry (see `NuGet.Config`)

3
.gitignore vendored
View file

@ -255,3 +255,6 @@ paket-files/
# JetBrains Rider
.idea/
*.sln.iml
.vscode/settings.json
tmp/**
TestArtifacts/**

159
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,159 @@
stages:
- build
- publish
# Only create pipelines automatically when a Git tag is pushed.
# Otherwise the pipeline must be started manually (pipeline "Run" / dispatch equivalent).
# workflow:
# rules:
# - if: '$CI_COMMIT_TAG'
# when: always
# - if: '$CI_PIPELINE_SOURCE == "web"'
# when: always
# - when: never
variables:
DOTNET_CLI_TELEMETRY_OPTOUT: "1"
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1"
BUILD_CONFIG: "Release"
# NOTE: This project uses repository variables for NuGet auth because secrets
# (masked/protected variables) may not be available on your GitLab plan.
# Replace the placeholders below with values in the repository, or override
# them in your project CI/CD variables when available.
# - NUGET_USERNAME : username (can be any value when using a PAT)
# - NUGET_PASSWORD : personal access token or project deploy token
NUGET_USERNAME: "REPLACE_WITH_USERNAME"
NUGET_PASSWORD: "REPLACE_WITH_TOKEN"
# Build job for Windows runner (shell executor). Remove 'image' so the runner uses the host environment.
build_windows:
stage: build
tags:
- saas-windows-medium-amd64
script:
- |
powershell -NoProfile -Command {
$needsInstall = -not (dotnet --list-sdks 2>$null | Select-String '^10\.')
if ($needsInstall) {
Write-Host 'Installing .NET 10 SDK using dotnet-install.ps1'
Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1 -UseBasicParsing
.\dotnet-install.ps1 -Channel 10.0 -InstallDir $env:USERPROFILE\.dotnet
$dotnetExe = Join-Path $env:USERPROFILE '.dotnet\dotnet.exe'
} else {
Write-Host '.NET 10 SDK already present on PATH'
$dotnetExe = 'dotnet'
}
# Configure private NuGet source from GitLab Packages using CI_JOB_TOKEN
# Fallback to repository variables NUGET_USERNAME/NUGET_PASSWORD for shared runners
$nugetUrl = 'https://gitlab.com/api/v4/projects/79509532/packages/nuget/index.json'
$authMode = $null
if ($env:CI_JOB_TOKEN) {
Write-Host 'Configuring private NuGet source Nuget-GitLab-AIFotoONLUS using CI_JOB_TOKEN...'
try { & $dotnetExe nuget remove source Nuget-GitLab-AIFotoONLUS } catch {}
& $dotnetExe nuget add source $nugetUrl --name Nuget-GitLab-AIFotoONLUS --username gitlab-ci-token --password $env:CI_JOB_TOKEN --store-password-in-clear-text
$authMode = 'JobToken'
} elseif ($env:NUGET_USERNAME -and $env:NUGET_PASSWORD) {
Write-Host 'Configuring private NuGet source Nuget-GitLab-AIFotoONLUS using NUGET_USERNAME/NUGET_PASSWORD...'
try { & $dotnetExe nuget remove source Nuget-GitLab-AIFotoONLUS } catch {}
& $dotnetExe nuget add source $nugetUrl --name Nuget-GitLab-AIFotoONLUS --username $env:NUGET_USERNAME --password $env:NUGET_PASSWORD --store-password-in-clear-text
$authMode = 'UserCreds'
} else {
Write-Host 'No credentials available; skipping private NuGet source configuration.'
}
& $dotnetExe --info
# Diagnostic: verify GitLab NuGet feed and package visibility using configured auth
if ($authMode) {
Write-Host 'Checking GitLab NuGet feed index and project packages for AIFotoONLUS.Core using auth mode:' $authMode
try {
if ($authMode -eq 'JobToken') {
$headers = @{ 'JOB-TOKEN' = $env:CI_JOB_TOKEN }
} else {
$pair = "$env:NUGET_USERNAME:$env:NUGET_PASSWORD"
$b64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($pair))
$headers = @{ Authorization = "Basic $b64" }
}
Invoke-RestMethod -Uri $nugetUrl -Headers $headers -Method Get | ConvertTo-Json | Write-Host
} catch { Write-Host "Failed to fetch feed index: $_" }
try {
$pkgApi = "https://gitlab.com/api/v4/projects/79509532/packages?package_name=AIFotoONLUS.Core"
Invoke-RestMethod -Uri $pkgApi -Headers $headers -Method Get | ConvertTo-Json | Write-Host
} catch { Write-Host "Failed to query project packages API: $_" }
} else {
Write-Host 'Skipping feed diagnostics because no auth configured.'
}
& $dotnetExe restore
& $dotnetExe build "imagecatalog\ImageCatalog 2.csproj" -c $env:BUILD_CONFIG -v minimal
# Produce a single-file, ready-to-run publish so downstream jobs only need the EXE.
try {
& $dotnetExe publish "imagecatalog\ImageCatalog 2.csproj" -c $env:BUILD_CONFIG -r win-x64 --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=false -p:PublishReadyToRun=true -o "imagecatalog\bin\$env:BUILD_CONFIG\net10.0-windows\publish" -v minimal
$publishDir = "imagecatalog\bin\$env:BUILD_CONFIG\net10.0-windows\publish"
$legacyRendererFiles = Get-ChildItem $publishDir -File | Where-Object { $_.Name -in @('Microsoft.Windows.Compatibility.dll', 'System.Private.Windows.GdiPlus.dll') }
if ($legacyRendererFiles) {
Write-Host 'Legacy GDI compatibility assemblies must not be published:'
$legacyRendererFiles | ForEach-Object { Write-Host $_.FullName }
exit 1
}
} catch {
Write-Host "dotnet publish failed: $_"
throw
}
}
artifacts:
paths:
- "imagecatalog/bin/$BUILD_CONFIG/net10.0-windows/publish/**"
expire_in: 1 hour
# Publish and create GitLab Release when building a tag.
publish_release:
stage: publish
image: mcr.microsoft.com/dotnet/sdk:10.0
variables:
GIT_DEPTH: 0
needs:
- job: build_windows
artifacts: true
script: |
set -euo pipefail
dotnet --info
export PATH="$PATH:$HOME/.dotnet/tools"
echo "Installing minver-cli"
dotnet tool install --global minver-cli --version 7.0.0
# Ensure we have full git history and tags for MinVer to compute an accurate version
git fetch --prune --unshallow || true
git fetch --tags || true
echo "Computing version with minver-cli"
version=$(minver 2>/dev/null | tail -n1 || true)
if [ -z "$version" ]; then echo "minver failed to produce a version"; exit 1; fi
echo "Using version: $version"
export VERSION="$version"
# find the single-file exe from the publish output
file=$(find imagecatalog/bin -type f -iname '*.exe' -print | head -n1 || true)
if [ -z "$file" ]; then file=$(find imagecatalog -type f -iname '*.exe' -print | head -n1 || true); fi
if [ -z "$file" ]; then echo "No artifact EXE found to attach"; exit 1; fi
echo "Uploading artifact: $file"
uploadResp=$(curl --silent --show-error --header "JOB-TOKEN:$CI_JOB_TOKEN" --form "file=@$file" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/uploads")
assetPath=$(echo "$uploadResp" | sed -n 's/.*"url":"\([^\"]*\)".*/\1/p')
if [ -z "$assetPath" ]; then echo "Upload failed: $uploadResp"; exit 1; fi
assetUrl="$CI_SERVER_URL$assetPath"
echo "Uploaded asset url: $assetUrl"
basename=$(basename "$file")
export RELEASE_ASSET_URL="$assetUrl"
export ASSET_BASENAME="$basename"
artifacts:
expire_in: 1 day
release:
tag_name: "$VERSION"
name: "Release $VERSION"
description: "Automated release from CI (version $VERSION)"
assets:
links:
- name: "$ASSET_BASENAME"
url: "$RELEASE_ASSET_URL"
# only:
# - tags
# Notes for runner setup: The job now runs on the public .NET SDK image and downloads artifacts from the
# `build_windows` job via `needs`. It reads the `minversion` file produced by the build artifacts and
# uses that value as the release tag.

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "MaddoLibrary"]
path = MaddoLibrary
url = git@gitlab.com:MaddoTools/MaddoLibrary.git

23
.gitversion.yml Normal file
View file

@ -0,0 +1,23 @@
mode: ContinuousDelivery
branches:
main:
tag: ''
increment: Patch
prevent-increment-of-merged-branch-version: true
track-merge-target: false
develop:
tag: alpha
increment: Minor
prevent-increment-of-merged-branch-version: false
feature:
tag: beta
increment: Patch
hotfix:
tag: hotfix
increment: Patch
release:
tag: rc
increment: Patch
ignore:
sha: []
commit-message-incrementing: Disabled

16
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,16 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "ImageCatalog Avalonia",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build ImageCatalog Avalonia",
"program": "${workspaceFolder:Catalog}/imagecatalog/bin/Debug/net10.0-windows/win-x64/ImageCatalog.exe",
"args": [],
"cwd": "${workspaceFolder:Catalog}/imagecatalog",
"stopAtEntry": false,
"console": "internalConsole"
}
]
}

18
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,18 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build ImageCatalog Avalonia",
"type": "process",
"command": "dotnet",
"args": [
"build",
"${workspaceFolder:Catalog}/imagecatalog/ImageCatalog 2.csproj",
"--configuration",
"Debug"
],
"problemMatcher": "$msCompile",
"group": "build"
}
]
}

View file

@ -0,0 +1,40 @@
using Catalog.Communication.Models;
namespace Catalog.Communication.Abstractions;
public interface IRaceUploadCommunicationClient
{
Task<RawEndpointResponse> LoginAdminAsync(AdminLoginRequest request, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> LogoutAdminAsync(CancellationToken cancellationToken = default);
Task<UploadImageResponse?> UploadRaceImageAsync(RaceImageUploadRequest request, CancellationToken cancellationToken = default);
Task<UploadImageResponse?> RemoveRaceImageAsync(RaceImageRemoveRequest request, CancellationToken cancellationToken = default);
Task<UploadFileResponse?> UploadRaceFileAsync(RaceFileUploadRequest request, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> SaveRaceAsync(RaceSaveRequest request, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> CreateRacePointsAsync(long raceId, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> IndexRacePointAsync(long pointId, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> GetRaceDetailAsync(long raceId, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> UploadFileToReceiverAsync(ReceiveFileUploadRequest request, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> ExecuteGaraCommandAsync(IReadOnlyDictionary<string, string?> formFields, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> ExecuteAdminPhotoCommandAsync(AdminPhotoEndpoint endpoint, IReadOnlyDictionary<string, string?> formFields, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> ExecutePublicLogonAsync(IReadOnlyDictionary<string, string?> formFields, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> ExecuteUsersAsync(HttpMethod method, IReadOnlyDictionary<string, string?>? formFields = null, CancellationToken cancellationToken = default);
Task<RawEndpointResponse> ExecuteFoto2Async(HttpMethod method, IReadOnlyDictionary<string, string?>? formFields = null, CancellationToken cancellationToken = default);
Task<MediaFileResponse> DownloadThumbnailAsync(string filename, long? idFoto = null, CancellationToken cancellationToken = default);
Task<MediaFileResponse> DownloadOriginalAsync(string filename, long? idFoto = null, CancellationToken cancellationToken = default);
}

View file

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<OutputType>Library</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.8" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,16 @@
namespace Catalog.Communication;
public sealed class CatalogCommunicationOptions
{
public required Uri BaseUri { get; set; }
public string AdminPageBasePath { get; set; } = "admin/pg";
public string ReceiveFilePath { get; set; } = "ReceiveFile.abl";
public TimeSpan RequestTimeout { get; set; } = TimeSpan.FromSeconds(30);
public int RetryCount { get; set; } = 2;
public TimeSpan RetryBaseDelay { get; set; } = TimeSpan.FromMilliseconds(250);
}

View file

@ -0,0 +1,57 @@
using System.Net;
using Catalog.Communication.Abstractions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
namespace Catalog.Communication.DependencyInjection;
public static class CatalogCommunicationServiceCollectionExtensions
{
public static IServiceCollection AddCatalogCommunication(this IServiceCollection services, Action<CatalogCommunicationOptions> configure)
{
ArgumentNullException.ThrowIfNull(services);
ArgumentNullException.ThrowIfNull(configure);
services
.AddOptions<CatalogCommunicationOptions>()
.Configure(configure)
.Validate(o => o.BaseUri is not null, "CatalogCommunicationOptions.BaseUri is required.")
.Validate(o => !string.IsNullOrWhiteSpace(o.AdminPageBasePath), "AdminPageBasePath is required.")
.Validate(o => !string.IsNullOrWhiteSpace(o.ReceiveFilePath), "ReceiveFilePath is required.")
.Validate(o => o.RequestTimeout > TimeSpan.Zero, "RequestTimeout must be greater than zero.")
.Validate(o => o.RetryCount >= 0 && o.RetryCount <= 10, "RetryCount must be between 0 and 10.")
.Validate(o => o.RetryBaseDelay > TimeSpan.Zero, "RetryBaseDelay must be greater than zero.");
services.TryAddSingleton<CookieContainer>();
// Create the HttpClient only when the communication client is requested.
// This avoids constructing the DefaultHttpClientFactory (and its background cleanup timer)
// if the race-upload feature is never used.
services.AddTransient<IRaceUploadCommunicationClient>(sp =>
{
var options = sp.GetRequiredService<IOptions<CatalogCommunicationOptions>>().Value;
var logger = sp.GetService<ILogger<RaceUploadCommunicationClient>>() ?? NullLogger<RaceUploadCommunicationClient>.Instance;
var cookieContainer = sp.GetRequiredService<CookieContainer>();
var handler = new HttpClientHandler
{
UseCookies = true,
CookieContainer = cookieContainer,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.Brotli,
};
var httpClient = new HttpClient(handler, disposeHandler: true)
{
BaseAddress = options.BaseUri,
Timeout = options.RequestTimeout,
};
return new RaceUploadCommunicationClient(httpClient, sp.GetRequiredService<IOptions<CatalogCommunicationOptions>>(), logger);
});
return services;
}
}

View file

@ -0,0 +1,10 @@
namespace Catalog.Communication.Models;
public sealed class AdminLoginRequest
{
public required string Login { get; init; }
public required string Password { get; init; }
public string Command { get; init; } = "check";
}

View file

@ -0,0 +1,8 @@
namespace Catalog.Communication.Models;
public enum AdminPhotoEndpoint
{
Foto = 0,
TipoGara = 1,
LogFoto = 2,
}

View file

@ -0,0 +1,16 @@
using System.Net;
namespace Catalog.Communication.Models;
public sealed class MediaFileResponse
{
public required HttpStatusCode StatusCode { get; init; }
public required byte[] Content { get; init; }
public string? ContentType { get; init; }
public string? FileName { get; init; }
public required IReadOnlyDictionary<string, IReadOnlyList<string>> Headers { get; init; }
}

View file

@ -0,0 +1,16 @@
namespace Catalog.Communication.Models;
public sealed class RaceFileUploadRequest
{
public int? CodFile { get; init; }
public long? Id { get; init; }
public required string FileName { get; init; }
public required Stream FileStream { get; init; }
public string FormFieldName { get; init; } = "fileName";
public string? ContentType { get; init; }
}

View file

@ -0,0 +1,10 @@
namespace Catalog.Communication.Models;
public sealed class RaceImageRemoveRequest
{
public required long Id { get; init; }
public required int CodImage { get; init; }
public int? TotImgNumber { get; init; }
}

View file

@ -0,0 +1,18 @@
namespace Catalog.Communication.Models;
public sealed class RaceImageUploadRequest
{
public required long Id { get; init; }
public required int CodImage { get; init; }
public int? TotImgNumber { get; init; }
public required string FileName { get; init; }
public required Stream FileStream { get; init; }
public string FormFieldName { get; init; } = "imgFile";
public string? ContentType { get; init; }
}

View file

@ -0,0 +1,26 @@
namespace Catalog.Communication.Models;
public sealed class RaceSaveRequest
{
public long IdGara { get; init; }
public required string Description { get; init; }
public required DateOnly StartDate { get; init; }
public DateOnly? EndDate { get; init; }
public required long TipoGaraId { get; init; }
public int EventoInLinea { get; init; }
public int TipoIndicizzazione { get; init; }
public int FreeEvent { get; init; }
public string? PathBase { get; init; }
public string? Localita { get; init; }
public long? CodGara { get; init; }
}

View file

@ -0,0 +1,12 @@
using System.Net;
namespace Catalog.Communication.Models;
public sealed class RawEndpointResponse
{
public required HttpStatusCode StatusCode { get; init; }
public required string Body { get; init; }
public required IReadOnlyDictionary<string, IReadOnlyList<string>> Headers { get; init; }
}

View file

@ -0,0 +1,16 @@
namespace Catalog.Communication.Models;
public sealed class ReceiveFileUploadRequest
{
public required string FileName { get; init; }
public required Stream FileStream { get; init; }
public required string DestinationPath { get; init; }
public bool OverwriteRemoteFile { get; init; }
public int? BufferSize { get; init; }
public string? ContentType { get; init; }
}

View file

@ -0,0 +1,18 @@
using System.Text.Json.Serialization;
namespace Catalog.Communication.Models;
public sealed class UploadFileResponse
{
[JsonPropertyName("result")]
public bool Result { get; init; }
[JsonPropertyName("message")]
public string Message { get; init; } = string.Empty;
[JsonPropertyName("fileName")]
public string FileName { get; init; } = string.Empty;
[JsonPropertyName("fileNameLink")]
public string FileNameLink { get; init; } = string.Empty;
}

View file

@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace Catalog.Communication.Models;
public sealed class UploadImageResponse
{
[JsonPropertyName("result")]
public bool Result { get; init; }
[JsonPropertyName("message")]
public string Message { get; init; } = string.Empty;
[JsonPropertyName("imgPath")]
public string ImgPath { get; init; } = string.Empty;
}

View file

@ -0,0 +1,622 @@
using System.Net;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Globalization;
using Catalog.Communication.Abstractions;
using Catalog.Communication.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Catalog.Communication;
public sealed class RaceUploadCommunicationClient : IRaceUploadCommunicationClient, IDisposable
{
private const string AdminMenuPath = "admin/menu/Menu4.abl";
private const string PublicLogonPath = "Logon.abl";
private const string UsersPath = "Users.abl";
private const string Foto2Path = "Foto2.abl";
private const string ThumbnailPath = "foto";
private const string OriginalPath = "fotoOriginali";
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web)
{
PropertyNameCaseInsensitive = true,
};
private readonly HttpClient _httpClient;
private readonly ILogger<RaceUploadCommunicationClient> _logger;
private readonly IOptions<CatalogCommunicationOptions> _options;
private bool _disposed;
public RaceUploadCommunicationClient(
HttpClient httpClient,
IOptions<CatalogCommunicationOptions> options,
ILogger<RaceUploadCommunicationClient> logger)
{
_httpClient = httpClient;
_options = options;
_logger = logger;
}
public void Dispose()
{
if (_disposed)
{
return;
}
_httpClient.Dispose();
_disposed = true;
GC.SuppressFinalize(this);
}
public Task<RawEndpointResponse> LoginAdminAsync(AdminLoginRequest request, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
var formFields = new Dictionary<string, string?>
{
["login"] = request.Login,
["pwd"] = request.Password,
["cmdIU"] = request.Command,
};
return PostFormAsync(AdminMenuPath, formFields, "admin-login", cancellationToken);
}
public Task<RawEndpointResponse> LogoutAdminAsync(CancellationToken cancellationToken = default)
{
var formFields = new Dictionary<string, string?>
{
["cmdIU"] = "login",
};
return PostFormAsync(AdminMenuPath, formFields, "admin-logout", cancellationToken);
}
public Task<UploadImageResponse?> UploadRaceImageAsync(RaceImageUploadRequest request, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
return PostMultipartAndParseUploadAsync<UploadImageResponse>(
GetAdminPagePath("Gara"),
"gara-upload-image",
request.FileStream,
request.FileName,
request.FormFieldName,
request.ContentType,
static fields =>
{
fields["cmd"] = "loadImg";
},
new Dictionary<string, string?>
{
["id"] = request.Id.ToString(System.Globalization.CultureInfo.InvariantCulture),
["codImage"] = request.CodImage.ToString(System.Globalization.CultureInfo.InvariantCulture),
["totImgNumber"] = request.TotImgNumber?.ToString(System.Globalization.CultureInfo.InvariantCulture),
},
cancellationToken);
}
public Task<UploadImageResponse?> RemoveRaceImageAsync(RaceImageRemoveRequest request, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
var fields = new Dictionary<string, string?>
{
["cmd"] = "removeImg",
["id"] = request.Id.ToString(System.Globalization.CultureInfo.InvariantCulture),
["codImage"] = request.CodImage.ToString(System.Globalization.CultureInfo.InvariantCulture),
["totImgNumber"] = request.TotImgNumber?.ToString(System.Globalization.CultureInfo.InvariantCulture),
};
return PostFormAndParseUploadAsync<UploadImageResponse>(GetAdminPagePath("Gara"), fields, "gara-remove-image", cancellationToken);
}
public Task<UploadFileResponse?> UploadRaceFileAsync(RaceFileUploadRequest request, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
return PostMultipartAndParseUploadAsync<UploadFileResponse>(
GetAdminPagePath("Gara"),
"gara-upload-file",
request.FileStream,
request.FileName,
request.FormFieldName,
request.ContentType,
static fields =>
{
fields["cmd"] = "saveFile";
},
new Dictionary<string, string?>
{
["codFile"] = request.CodFile?.ToString(System.Globalization.CultureInfo.InvariantCulture),
["id"] = request.Id?.ToString(System.Globalization.CultureInfo.InvariantCulture),
},
cancellationToken);
}
public Task<RawEndpointResponse> SaveRaceAsync(RaceSaveRequest request, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
var formFields = new Dictionary<string, string?>
{
["cmd"] = "asq",
["act"] = "save",
["id_gara"] = request.IdGara.ToString(CultureInfo.InvariantCulture),
["descrizione"] = request.Description,
["dataGaraInizio"] = request.StartDate.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture),
["dataGaraFine"] = (request.EndDate ?? request.StartDate).ToString("dd/MM/yyyy", CultureInfo.InvariantCulture),
["id_tipoGara"] = request.TipoGaraId.ToString(CultureInfo.InvariantCulture),
["flgEventoInLinea"] = request.EventoInLinea.ToString(CultureInfo.InvariantCulture),
["flgTipoIndex"] = request.TipoIndicizzazione.ToString(CultureInfo.InvariantCulture),
["flgFree"] = request.FreeEvent.ToString(CultureInfo.InvariantCulture),
["pathBase"] = request.PathBase,
["localita"] = request.Localita,
["codGara"] = request.CodGara?.ToString(CultureInfo.InvariantCulture),
};
return PostFormAsync(GetAdminPagePath("Gara"), formFields, "gara-save", cancellationToken);
}
public Task<RawEndpointResponse> CreateRacePointsAsync(long raceId, CancellationToken cancellationToken = default)
{
var formFields = new Dictionary<string, string?>
{
["cmd"] = "creaPuntiFoto",
["id_gara"] = raceId.ToString(CultureInfo.InvariantCulture),
};
return PostFormAsync(GetAdminPagePath("Gara"), formFields, "gara-create-points", cancellationToken);
}
public Task<RawEndpointResponse> IndexRacePointAsync(long pointId, CancellationToken cancellationToken = default)
{
var formFields = new Dictionary<string, string?>
{
["cmd"] = "indexFoto",
["id_puntoFotoIdx"] = pointId.ToString(CultureInfo.InvariantCulture),
};
return PostFormAsync(GetAdminPagePath("Gara"), formFields, "gara-index-point", cancellationToken);
}
public Task<RawEndpointResponse> GetRaceDetailAsync(long raceId, CancellationToken cancellationToken = default)
{
var formFields = new Dictionary<string, string?>
{
["cmd"] = "search",
["id_gara"] = raceId.ToString(CultureInfo.InvariantCulture),
};
return PostFormAsync(GetAdminPagePath("Gara"), formFields, "gara-detail", cancellationToken);
}
public async Task<RawEndpointResponse> UploadFileToReceiverAsync(ReceiveFileUploadRequest request, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
ArgumentException.ThrowIfNullOrWhiteSpace(request.FileName);
ArgumentException.ThrowIfNullOrWhiteSpace(request.DestinationPath);
ArgumentNullException.ThrowIfNull(request.FileStream);
var payload = await ReadAllBytesAsync(request.FileStream, cancellationToken).ConfigureAwait(false);
var query = new Dictionary<string, string?>
{
["name"] = request.FileName,
["path"] = request.DestinationPath,
["overwriteRemoteFile"] = request.OverwriteRemoteFile ? "true" : "false",
["bs"] = request.BufferSize?.ToString(CultureInfo.InvariantCulture),
};
var path = AppendQuery(GetReceiveFilePath(), query);
return await ExecuteWithResilienceAsync(
() =>
{
var byteContent = new ByteArrayContent(payload);
byteContent.Headers.ContentType = new MediaTypeHeaderValue(request.ContentType ?? "application/octet-stream");
return new HttpRequestMessage(HttpMethod.Post, path)
{
Content = byteContent,
};
},
ToRawResponseAsync,
"receiver-upload",
cancellationToken).ConfigureAwait(false);
}
public Task<RawEndpointResponse> ExecuteGaraCommandAsync(IReadOnlyDictionary<string, string?> formFields, CancellationToken cancellationToken = default)
{
return PostFormAsync(GetAdminPagePath("Gara"), formFields, "gara-command", cancellationToken);
}
public Task<RawEndpointResponse> ExecuteAdminPhotoCommandAsync(AdminPhotoEndpoint endpoint, IReadOnlyDictionary<string, string?> formFields, CancellationToken cancellationToken = default)
{
var path = endpoint switch
{
AdminPhotoEndpoint.Foto => GetAdminPagePath("Foto"),
AdminPhotoEndpoint.TipoGara => GetAdminPagePath("TipoGara"),
AdminPhotoEndpoint.LogFoto => GetAdminPagePath("LogFoto"),
_ => throw new ArgumentOutOfRangeException(nameof(endpoint), endpoint, "Unsupported endpoint."),
};
return PostFormAsync(path, formFields, $"photo-admin-{endpoint}", cancellationToken);
}
public Task<RawEndpointResponse> ExecutePublicLogonAsync(IReadOnlyDictionary<string, string?> formFields, CancellationToken cancellationToken = default)
{
return PostFormAsync(PublicLogonPath, formFields, "public-logon", cancellationToken);
}
public Task<RawEndpointResponse> ExecuteUsersAsync(HttpMethod method, IReadOnlyDictionary<string, string?>? formFields = null, CancellationToken cancellationToken = default)
{
return SendCommandAsync(method, UsersPath, formFields, "public-users", cancellationToken);
}
public Task<RawEndpointResponse> ExecuteFoto2Async(HttpMethod method, IReadOnlyDictionary<string, string?>? formFields = null, CancellationToken cancellationToken = default)
{
return SendCommandAsync(method, Foto2Path, formFields, "public-foto2", cancellationToken);
}
public Task<MediaFileResponse> DownloadThumbnailAsync(string filename, long? idFoto = null, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(filename);
return DownloadFileAsync(ThumbnailPath, filename, idFoto, "media-thumbnail", cancellationToken);
}
public Task<MediaFileResponse> DownloadOriginalAsync(string filename, long? idFoto = null, CancellationToken cancellationToken = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(filename);
return DownloadFileAsync(OriginalPath, filename, idFoto, "media-original", cancellationToken);
}
private Task<RawEndpointResponse> SendCommandAsync(HttpMethod method, string path, IReadOnlyDictionary<string, string?>? formFields, string operationName, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(method);
if (method == HttpMethod.Get)
{
var relativePath = AppendQuery(path, formFields);
return GetAsync(relativePath, operationName, cancellationToken);
}
if (method == HttpMethod.Post)
{
return PostFormAsync(path, formFields ?? new Dictionary<string, string?>(), operationName, cancellationToken);
}
throw new NotSupportedException($"Only GET and POST are supported. Requested method: {method}.");
}
private Task<RawEndpointResponse> GetAsync(string relativePath, string operationName, CancellationToken cancellationToken)
{
return ExecuteWithResilienceAsync(
() => new HttpRequestMessage(HttpMethod.Get, relativePath),
ToRawResponseAsync,
operationName,
cancellationToken);
}
private Task<RawEndpointResponse> PostFormAsync(string relativePath, IReadOnlyDictionary<string, string?> formFields, string operationName, CancellationToken cancellationToken)
{
return ExecuteWithResilienceAsync(
() =>
{
var request = new HttpRequestMessage(HttpMethod.Post, relativePath)
{
Content = BuildFormContent(formFields),
};
return request;
},
ToRawResponseAsync,
operationName,
cancellationToken);
}
private Task<TUpload?> PostFormAndParseUploadAsync<TUpload>(string relativePath, IReadOnlyDictionary<string, string?> formFields, string operationName, CancellationToken cancellationToken)
{
return ExecuteWithResilienceAsync(
() =>
{
var request = new HttpRequestMessage(HttpMethod.Post, relativePath)
{
Content = BuildFormContent(formFields),
};
return request;
},
async (response, token) =>
{
var raw = await ToRawResponseAsync(response, token).ConfigureAwait(false);
return ParseSingleItemArray<TUpload>(raw.Body);
},
operationName,
cancellationToken);
}
private async Task<TUpload?> PostMultipartAndParseUploadAsync<TUpload>(
string relativePath,
string operationName,
Stream fileStream,
string fileName,
string formFieldName,
string? contentType,
Action<Dictionary<string, string?>> configureRequiredFields,
IReadOnlyDictionary<string, string?> optionalFields,
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(fileStream);
ArgumentException.ThrowIfNullOrWhiteSpace(fileName);
ArgumentException.ThrowIfNullOrWhiteSpace(formFieldName);
var payload = await ReadAllBytesAsync(fileStream, cancellationToken).ConfigureAwait(false);
return await ExecuteWithResilienceAsync(
() =>
{
var multipart = new MultipartFormDataContent();
var fields = new Dictionary<string, string?>();
configureRequiredFields(fields);
foreach (var field in fields)
{
if (string.IsNullOrWhiteSpace(field.Value))
{
continue;
}
multipart.Add(new StringContent(field.Value, Encoding.UTF8), field.Key);
}
foreach (var field in optionalFields)
{
if (string.IsNullOrWhiteSpace(field.Value))
{
continue;
}
multipart.Add(new StringContent(field.Value, Encoding.UTF8), field.Key);
}
var fileContent = new ByteArrayContent(payload);
fileContent.Headers.ContentType = new MediaTypeHeaderValue(contentType ?? "application/octet-stream");
multipart.Add(fileContent, formFieldName, fileName);
return new HttpRequestMessage(HttpMethod.Post, relativePath)
{
Content = multipart,
};
},
async (response, token) =>
{
var raw = await ToRawResponseAsync(response, token).ConfigureAwait(false);
return ParseSingleItemArray<TUpload>(raw.Body);
},
operationName,
cancellationToken).ConfigureAwait(false);
}
private Task<MediaFileResponse> DownloadFileAsync(string basePath, string filename, long? idFoto, string operationName, CancellationToken cancellationToken)
{
var escapedFileName = Uri.EscapeDataString(filename);
var relativePath = idFoto.HasValue
? $"{basePath}/{escapedFileName}?id_foto={idFoto.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)}"
: $"{basePath}/{escapedFileName}";
return ExecuteWithResilienceAsync(
() => new HttpRequestMessage(HttpMethod.Get, relativePath),
async (response, token) =>
{
var content = await response.Content.ReadAsByteArrayAsync(token).ConfigureAwait(false);
return new MediaFileResponse
{
StatusCode = response.StatusCode,
Content = content,
ContentType = response.Content.Headers.ContentType?.MediaType,
FileName = response.Content.Headers.ContentDisposition?.FileNameStar ?? response.Content.Headers.ContentDisposition?.FileName,
Headers = BuildHeaders(response),
};
},
operationName,
cancellationToken);
}
private async Task<TResponse> ExecuteWithResilienceAsync<TResponse>(
Func<HttpRequestMessage> requestFactory,
Func<HttpResponseMessage, CancellationToken, Task<TResponse>> responseFactory,
string operationName,
CancellationToken cancellationToken)
{
var options = _options.Value;
Exception? lastException = null;
for (var attempt = 0; attempt <= options.RetryCount; attempt++)
{
using var request = requestFactory();
using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
timeoutCts.CancelAfter(options.RequestTimeout);
HttpResponseMessage? response = null;
try
{
response = await _httpClient
.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, timeoutCts.Token)
.ConfigureAwait(false);
if (IsRetryableStatusCode(response.StatusCode) && attempt < options.RetryCount)
{
_logger.LogWarning(
"Operation {OperationName} received retryable status code {StatusCode} at attempt {Attempt}/{MaxAttempts}.",
operationName,
(int)response.StatusCode,
attempt + 1,
options.RetryCount + 1);
await DelayBeforeRetryAsync(options, attempt, cancellationToken).ConfigureAwait(false);
continue;
}
return await responseFactory(response, cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException ex) when (!cancellationToken.IsCancellationRequested)
{
lastException = ex;
if (attempt < options.RetryCount)
{
_logger.LogWarning(ex, "Operation {OperationName} timed out at attempt {Attempt}/{MaxAttempts}.", operationName, attempt + 1, options.RetryCount + 1);
await DelayBeforeRetryAsync(options, attempt, cancellationToken).ConfigureAwait(false);
continue;
}
_logger.LogError(ex, "Operation {OperationName} timed out after {MaxAttempts} attempts.", operationName, options.RetryCount + 1);
throw;
}
catch (HttpRequestException ex)
{
lastException = ex;
if (attempt < options.RetryCount)
{
_logger.LogWarning(ex, "Operation {OperationName} failed with transient HTTP error at attempt {Attempt}/{MaxAttempts}.", operationName, attempt + 1, options.RetryCount + 1);
await DelayBeforeRetryAsync(options, attempt, cancellationToken).ConfigureAwait(false);
continue;
}
_logger.LogError(ex, "Operation {OperationName} failed with HTTP error after {MaxAttempts} attempts.", operationName, options.RetryCount + 1);
throw;
}
catch (Exception ex)
{
_logger.LogError(ex, "Operation {OperationName} failed with unexpected error at attempt {Attempt}/{MaxAttempts}.", operationName, attempt + 1, options.RetryCount + 1);
throw;
}
finally
{
response?.Dispose();
}
}
throw new HttpRequestException($"Operation '{operationName}' failed after {options.RetryCount + 1} attempts.", lastException);
}
private static bool IsRetryableStatusCode(HttpStatusCode statusCode)
{
return statusCode is HttpStatusCode.RequestTimeout
or HttpStatusCode.TooManyRequests
or HttpStatusCode.BadGateway
or HttpStatusCode.ServiceUnavailable
or HttpStatusCode.GatewayTimeout
or HttpStatusCode.InternalServerError;
}
private static async Task DelayBeforeRetryAsync(CatalogCommunicationOptions options, int attempt, CancellationToken cancellationToken)
{
var delay = TimeSpan.FromMilliseconds(options.RetryBaseDelay.TotalMilliseconds * Math.Pow(2, attempt));
await Task.Delay(delay, cancellationToken).ConfigureAwait(false);
}
private static FormUrlEncodedContent BuildFormContent(IReadOnlyDictionary<string, string?> formFields)
{
var pairs = formFields
.Where(kvp => !string.IsNullOrWhiteSpace(kvp.Value))
.Select(kvp => new KeyValuePair<string, string>(kvp.Key, kvp.Value!));
return new FormUrlEncodedContent(pairs);
}
private static string AppendQuery(string path, IReadOnlyDictionary<string, string?>? query)
{
if (query is null || query.Count == 0)
{
return path;
}
var encodedPairs = query
.Where(kvp => !string.IsNullOrWhiteSpace(kvp.Value))
.Select(kvp => $"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value!)}")
.ToArray();
if (encodedPairs.Length == 0)
{
return path;
}
var separator = path.Contains('?', StringComparison.Ordinal) ? "&" : "?";
return string.Concat(path, separator, string.Join("&", encodedPairs));
}
private static async Task<RawEndpointResponse> ToRawResponseAsync(HttpResponseMessage response, CancellationToken cancellationToken)
{
var body = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
return new RawEndpointResponse
{
StatusCode = response.StatusCode,
Body = body,
Headers = BuildHeaders(response),
};
}
private static IReadOnlyDictionary<string, IReadOnlyList<string>> BuildHeaders(HttpResponseMessage response)
{
var headers = new Dictionary<string, IReadOnlyList<string>>(StringComparer.OrdinalIgnoreCase);
foreach (var header in response.Headers)
{
headers[header.Key] = header.Value.ToArray();
}
foreach (var header in response.Content.Headers)
{
headers[header.Key] = header.Value.ToArray();
}
return headers;
}
private static TUpload? ParseSingleItemArray<TUpload>(string json)
{
if (string.IsNullOrWhiteSpace(json))
{
return default;
}
var items = JsonSerializer.Deserialize<List<TUpload>>(json, JsonOptions);
return items is { Count: > 0 } ? items[0] : default;
}
private static async Task<byte[]> ReadAllBytesAsync(Stream stream, CancellationToken cancellationToken)
{
if (stream.CanSeek)
{
stream.Position = 0;
}
using var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false);
return memoryStream.ToArray();
}
private string GetAdminPagePath(string pageName)
{
var basePath = _options.Value.AdminPageBasePath.Trim('/');
return $"{basePath}/{pageName}.abl";
}
private string GetReceiveFilePath()
{
var value = _options.Value.ReceiveFilePath;
if (string.IsNullOrWhiteSpace(value))
{
return "ReceiveFile.abl";
}
return value.Trim();
}
}

17
Catalog.code-workspace Normal file
View file

@ -0,0 +1,17 @@
{
"folders": [
{
"path": "."
},
{
"path": "../AIFotoONLUS"
},
{
"path": "../../various/regalamiunsorriso"
}
],
"settings": {
"commentTranslate.hover.enabled": false,
"github.copilot.chat.otel.dbSpanExporter.enabled": true
}
}

View file

@ -1,122 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35312.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageCatalog 2", "imagecatalog\ImageCatalog 2.csproj", "{3F1E23DB-435E-0590-1EF5-735E898DBA3C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageCatalog 3", "ImageCatalogCS\ImageCatalog 3.csproj", "{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalogLib", "CatalogLib\CatalogLib.csproj", "{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFCatalog", "WPFCatalog\WPFCatalog.csproj", "{638DE501-CECA-4744-B293-7AE93CAEEB01}"
EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CatalogVbLib", "CatalogVbLib\CatalogVbLib.vbproj", "{44465926-240D-473F-90B8-786BA4384406}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{A3D50937-74F6-4DC8-8D89-B534B484C0F9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MaddoShared", "MaddoShared\MaddoShared.csproj", "{AEBFE9E3-277C-4A7B-8448-145D1B11998B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageCatalogParallel", "ImageCatalogParallel\ImageCatalogParallel.csproj", "{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaddoLibrary.Base.NET46", "MaddoLibrary\MaddoLibrary.Base.NET46\MaddoLibrary.Base.NET46.csproj", "{E93DAAE6-4AA9-4A45-AFB6-58209B3AD3C9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaddoLibrary.WPF.NET46", "MaddoLibrary\MaddoLibrary.WPF.NET46\MaddoLibrary.WPF.NET46.csproj", "{73DA19D7-196D-4B16-B610-93250978A607}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Debug|x64.ActiveCfg = Debug|Any CPU
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Debug|x64.Build.0 = Debug|Any CPU
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Debug|x86.ActiveCfg = Debug|x86
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Debug|x86.Build.0 = Debug|x86
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Release|Any CPU.Build.0 = Release|Any CPU
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Release|x64.ActiveCfg = Release|x64
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Release|x64.Build.0 = Release|x64
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Release|x86.ActiveCfg = Release|x86
{3F1E23DB-435E-0590-1EF5-735E898DBA3C}.Release|x86.Build.0 = Release|x86
{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}.Debug|x64.ActiveCfg = Debug|x64
{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}.Debug|x64.Build.0 = Debug|x64
{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}.Debug|x86.ActiveCfg = Debug|Any CPU
{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}.Release|Any CPU.Build.0 = Release|Any CPU
{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}.Release|x64.ActiveCfg = Release|x64
{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}.Release|x64.Build.0 = Release|x64
{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}.Release|x86.ActiveCfg = Release|Any CPU
{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}.Debug|x64.ActiveCfg = Debug|x64
{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}.Debug|x64.Build.0 = Debug|x64
{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}.Debug|x86.ActiveCfg = Debug|Any CPU
{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}.Release|Any CPU.Build.0 = Release|Any CPU
{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}.Release|x64.ActiveCfg = Release|x64
{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}.Release|x64.Build.0 = Release|x64
{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}.Release|x86.ActiveCfg = Release|Any CPU
{638DE501-CECA-4744-B293-7AE93CAEEB01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{638DE501-CECA-4744-B293-7AE93CAEEB01}.Debug|Any CPU.Build.0 = Debug|Any CPU
{638DE501-CECA-4744-B293-7AE93CAEEB01}.Debug|x64.ActiveCfg = Debug|x64
{638DE501-CECA-4744-B293-7AE93CAEEB01}.Debug|x64.Build.0 = Debug|x64
{638DE501-CECA-4744-B293-7AE93CAEEB01}.Debug|x86.ActiveCfg = Debug|Any CPU
{638DE501-CECA-4744-B293-7AE93CAEEB01}.Release|Any CPU.ActiveCfg = Release|Any CPU
{638DE501-CECA-4744-B293-7AE93CAEEB01}.Release|Any CPU.Build.0 = Release|Any CPU
{638DE501-CECA-4744-B293-7AE93CAEEB01}.Release|x64.ActiveCfg = Release|x64
{638DE501-CECA-4744-B293-7AE93CAEEB01}.Release|x64.Build.0 = Release|x64
{638DE501-CECA-4744-B293-7AE93CAEEB01}.Release|x86.ActiveCfg = Release|Any CPU
{44465926-240D-473F-90B8-786BA4384406}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44465926-240D-473F-90B8-786BA4384406}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44465926-240D-473F-90B8-786BA4384406}.Debug|x64.ActiveCfg = Debug|x64
{44465926-240D-473F-90B8-786BA4384406}.Debug|x64.Build.0 = Debug|x64
{44465926-240D-473F-90B8-786BA4384406}.Debug|x86.ActiveCfg = Debug|Any CPU
{44465926-240D-473F-90B8-786BA4384406}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44465926-240D-473F-90B8-786BA4384406}.Release|Any CPU.Build.0 = Release|Any CPU
{44465926-240D-473F-90B8-786BA4384406}.Release|x64.ActiveCfg = Release|x64
{44465926-240D-473F-90B8-786BA4384406}.Release|x64.Build.0 = Release|x64
{44465926-240D-473F-90B8-786BA4384406}.Release|x86.ActiveCfg = Release|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Debug|x64.ActiveCfg = Debug|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Debug|x64.Build.0 = Debug|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Debug|x86.ActiveCfg = Debug|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Debug|x86.Build.0 = Debug|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Release|Any CPU.Build.0 = Release|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Release|x64.ActiveCfg = Release|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Release|x64.Build.0 = Release|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Release|x86.ActiveCfg = Release|Any CPU
{AEBFE9E3-277C-4A7B-8448-145D1B11998B}.Release|x86.Build.0 = Release|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Debug|x64.ActiveCfg = Debug|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Debug|x64.Build.0 = Debug|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Debug|x86.ActiveCfg = Debug|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Debug|x86.Build.0 = Debug|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Release|Any CPU.Build.0 = Release|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Release|x64.ActiveCfg = Release|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Release|x64.Build.0 = Release|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Release|x86.ActiveCfg = Release|Any CPU
{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{AEBFE9E3-277C-4A7B-8448-145D1B11998B} = {A3D50937-74F6-4DC8-8D89-B534B484C0F9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0E3ABC63-8601-4DAC-AFEA-33F3E8E36757}
EndGlobalSection
EndGlobal

21
Catalog.slnx Normal file
View file

@ -0,0 +1,21 @@
<Solution>
<Configurations>
<Platform Name="Any CPU" />
<Platform Name="x64" />
<Platform Name="x86" />
</Configurations>
<Folder Name="/Libraries/">
<Project Path="Catalog.Communication/Catalog.Communication.csproj" />
<Project Path="MaddoShared/MaddoShared.csproj" />
</Folder>
<Folder Name="/Tests/">
<Project Path="MaddoShared.Tests/MaddoShared.Tests.csproj" />
</Folder>
<Project Path="imagecatalog/ImageCatalog 2.csproj">
<Platform Solution="*|x86" Project="x86" />
<Platform Solution="Release|x64" Project="x64" />
</Project>
<Project Path="CatalogLite/CatalogLite.csproj" />
<Project Path="MaddoShared.Benchmarks/MaddoShared.Benchmarks.csproj" />
<Project Path="MaddoShared.ImageSharpTests/MaddoShared.ImageSharpTests.csproj" />
</Solution>

View file

@ -1,196 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D27ACCF2-80FC-4DE8-AEB8-351FF076E6D5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CatalogLib</RootNamespace>
<AssemblyName>CatalogLib</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SixLabors.Core, Version=0.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SixLabors.Core.1.0.0-beta0002\lib\netstandard1.1\SixLabors.Core.dll</HintPath>
</Reference>
<Reference Include="SixLabors.Fonts, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SixLabors.Fonts.1.0.0-beta0001\lib\netstandard1.3\SixLabors.Fonts.dll</HintPath>
</Reference>
<Reference Include="SixLabors.ImageSharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SixLabors.ImageSharp.1.0.0-beta0001\lib\netstandard1.3\SixLabors.ImageSharp.dll</HintPath>
</Reference>
<Reference Include="SixLabors.ImageSharp.Drawing, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SixLabors.ImageSharp.Drawing.1.0.0-beta0001\lib\netstandard1.1\SixLabors.ImageSharp.Drawing.dll</HintPath>
</Reference>
<Reference Include="SixLabors.Shapes, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SixLabors.Shapes.1.0.0-beta0001\lib\netstandard1.1\SixLabors.Shapes.dll</HintPath>
</Reference>
<Reference Include="SixLabors.Shapes.Text, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SixLabors.Shapes.Text.1.0.0-beta0001\lib\netstandard1.1\SixLabors.Shapes.Text.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.AppContext, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll</HintPath>
</Reference>
<Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard1.1\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Collections.Immutable, Version=1.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.4.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.4.0-preview2-25405-01\lib\netstandard1.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll</HintPath>
</Reference>
<Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.4.0\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net46\System.Security.Cryptography.Algorithms.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net46\System.Security.Cryptography.X509Certificates.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Enums.cs" />
<Compile Include="IImageProcessor.cs" />
<Compile Include="ImageCreator.cs" />
<Compile Include="ImageCreator2.cs" />
<Compile Include="ImgSharpCreator.cs" />
<Compile Include="PicSettings.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SinglePicData.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CatalogVbLib\CatalogVbLib.vbproj">
<Project>{44465926-240d-473f-90b8-786ba4384406}</Project>
<Name>CatalogVbLib</Name>
</ProjectReference>
<ProjectReference Include="..\MaddoLibrary\MaddoLibrary.Base.NET46\MaddoLibrary.Base.NET46.csproj">
<Project>{e93daae6-4aa9-4a45-afb6-58209b3ad3c9}</Project>
<Name>MaddoLibrary.Base.NET46</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="stylecop.json" />
</ItemGroup>
<ItemGroup>
<Folder Include="Settings\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CatalogLib
{
public class Class1
{
}
}

View file

@ -1,41 +0,0 @@
namespace CatalogLib
{
public enum Positions
{
Alto,
Centro,
Basso
}
public enum Alignments
{
Sinistra,
Centro,
Destra
}
public enum ResizeModes
{
Bicubic,
Box,
CatmullRom,
Hermite,
Lanczos2,
Lanczos3,
Lanczos5,
Lanczos8,
MitchellNetravali,
NearestNeighbor,
Robidoux,
Spline,
Triangle,
Welch
}
public enum ResizeDimensions
{
LatoLungo,
LatoCorto
}
}

View file

@ -1,618 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using CatalogVbLib;
namespace CatalogLib
{
public class ImageCreator
{
#region Variabili
private SinglePicData _singlePicData;
private PicSettings _picSettings;
private Rotazione _rotation;
//private bool FotoRuotaADestra = false;
//private bool FotoRuotaASinistra = false;
private string TempMinText = "";
//Private crFont1 As Font
private string _NomeFileChild;
private DirectoryInfo _SourceDir;
private DirectoryInfo _DestDirStart;
private DirectoryInfo _DestDir;
private FileInfo _workFile;
private string testoFirma;
private string testoFirmaV;
private int alphaScelta;
private int _dimensioneStandard;
private int _dimensioneStandardMiniatura;
private DateTime dataFoto;
private DateTime dataPartenzaI;
private string testoOrario;
private string testoFirmaPiccola;
private Size thumbSizeSmall;
private Size thumbSizeBig;
private string nomeFileSmall;
private string nomeFileBig;
private string nomeFileBig2;
private float yPosFromBottom;
private float yPosFromBottom1;
private float yPosFromBottom2;
private float yPosFromBottom3;
private float yPosFromBottom4;
public string NomeFileChild
{
get { return _NomeFileChild; }
set { _NomeFileChild = value; }
}
public DirectoryInfo DestDirStart
{
get { return _DestDirStart; }
set { _DestDirStart = value; }
}
public DirectoryInfo SourceDir
{
get { return _SourceDir; }
set { _SourceDir = value; }
}
public DirectoryInfo DestDir
{
get { return _DestDir; }
set { _DestDir = value; }
}
public FileInfo WorkFile
{
get { return _workFile; }
set { _workFile = value; }
}
#endregion
//public ImageCreator(string nomeFileChild, DirectoryInfo sourceDir, DirectoryInfo destDir, DirectoryInfo destDirStart)
//{
// this.NomeFileChild = nomeFileChild;
// SourceDir = sourceDir;
// DestDir = destDir;
// DestDirStart = destDirStart;
// WorkFile = new FileInfo(nomeFileChild);
//}
//public ImageCreator(string nomeFileChild, DirectoryInfo sourceDir, DirectoryInfo destDir)
//{
// NomeFileChild = nomeFileChild;
// DestDir = destDir;
//}
//public ImageCreator(FileInfo file, DirectoryInfo destination)
//{
// WorkFile = file;
// DestDir = destination;
//}
public ImageCreator(SinglePicData picData, PicSettings picSettings)
{
}
/// <summary>
/// Elabora l'immagine
/// </summary>
/// <param name="info">Non ne ho idea. ToDo: capire a che serve</param>
public void CreaImmagineThread(string info)
{
//CatalogLib.PicSettings ps = new CatalogLib.PicSettings();
PreparaVariabili();
// Workfile deve essere impostato esternamente. ToDo: passarlo come parametro così da potere riutilizzare la classe senza eliminarla e ricrearla
Image g = Image.FromFile(WorkFile.FullName);
ImpostaTestoExtra(g);
// Rotazione immagine in base ai dati EXIF
Rotation(ref g);
// Impostazione del formato
// todo: mettere una selezione più specifica invece di assumere jpg
ImageFormat currentFormat = g.RawFormat;
if (_picSettings.UsaForzaJpg)
{
currentFormat = ImageFormat.Jpeg;
}
PrepareThumbnailSize(g);
// big image resolution
var imgOutputBig = new Bitmap(g, thumbSizeBig.Width, thumbSizeBig.Height);
imgOutputBig.SetResolution(g.HorizontalResolution, g.VerticalResolution);
if (_picSettings.CreaMiniature)
{
CreaMiniature(g, imgOutputBig, currentFormat);
}
}
private void Rotation(ref System.Drawing.Image g)
{
//FotoRuotaADestra = false;
//FotoRuotaASinistra = false;
_rotation = Rotazione.Normale;
if (_picSettings.GeneraleRotazioneAutomatica)
{
// ci sono dati exif
if (g.PropertyIdList.Length > 0)
{
ExifReader DatiExif = new ExifReader((Bitmap)g);
switch (DatiExif.Orientation)
{
case ExifReader.Orientations.BottomLeft:
break;
case ExifReader.Orientations.BottomRight:
break;
case ExifReader.Orientations.LeftTop:
break;
case ExifReader.Orientations.LftBottom:
//FotoRuotaASinistra = true;
_rotation = Rotazione.Sinistra;
break;
case ExifReader.Orientations.RightBottom:
break;
case ExifReader.Orientations.RightTop:
break;
case ExifReader.Orientations.TopLeft:
break;
case ExifReader.Orientations.TopRight:
break;
}
}
}
if (_rotation == Rotazione.Sinistra)
{
g.RotateFlip(RotateFlipType.Rotate270FlipNone);
}else
if (_rotation == Rotazione.Destra)
{
g.RotateFlip(RotateFlipType.Rotate90FlipNone);
}
// todo: capire quando va ruotato a destra
}
/// <summary>
/// Aggiunge orario e tempo gara
/// </summary>
/// <param name="g"></param>
private void ImpostaTestoExtra(Image g)
{
if (_picSettings.UsaOrarioTestoApplicare ||
_picSettings.UsaTempoGaraTestoApplicare ||
_picSettings.UsaOrarioMiniatura ||
_picSettings.TestoMin ||
_picSettings.AggTempoGaraMin ||
_picSettings.AggNumTempMin)
{
if (g.PropertyIdList.Length > 0) //ci sono dati exif
{
var datiExix = new ExifReader((Bitmap)g);
dataFoto = datiExix.DateTimeOriginal;
testoFirma = _picSettings.TestoFirmaStart;
testoFirmaV = _picSettings.TestoFirmaStartV;
if (dataFoto.Year != 1)
{
testoFirmaPiccola = dataFoto.ToShortDateString();
if (_picSettings.UsaOrarioTestoApplicare)
{
testoFirma = $"{testoFirma} {dataFoto.ToShortDateString()} {dataFoto.ToLongDateString()}";
testoFirmaV = $"{testoFirmaV} {dataFoto.ToShortDateString()} {dataFoto.ToLongDateString()}";
//testoFirma = string.Concat(testoFirma, " ", dataFoto.ToShortDateString(), " ", dataFoto.ToLongDateString());
//testoFirmaV = string.Concat(testoFirmaV, " ", dataFoto.ToShortDateString(), " ", dataFoto.ToLongDateString());
}
if (_picSettings.UsaTempoGaraTestoApplicare)
{
//TimeSpan orario = dataPartenzaI - dataFoto;
string orarioString = (dataPartenzaI - dataFoto).ToString(@"hh\:mm\:ss");
testoFirma = $"{testoFirma} {testoOrario} {orarioString}";
testoFirmaV = $"{testoFirmaV} {testoOrario} {orarioString}";
//testoFirma = string.Concat(testoFirma, " ", testoOrario, orario.ToString(@"hh\:mm\:ss"));
//testoFirmaV = string.Concat(testoFirmaV, " ", testoOrario, orario.ToString(@"hh\:mm\:ss"));
}
}
}
}
else
{
testoFirma = _picSettings.TestoFirmaStart;
testoFirmaV = _picSettings.TestoFirmaStartV;
}
}
/// <summary>
/// Preparazione delle variabili a valori di default e caricamento da impostazioni
/// </summary>
private void PreparaVariabili()
{
alphaScelta = (int)(255 * (100 - _picSettings.Trasparenza) / 100);
testoFirma = string.Empty;
testoFirmaV = string.Empty;
dataPartenzaI = _picSettings.DataPartenza;
testoOrario = _picSettings.TestoOrario;
if (testoOrario.Length > 0)
{
testoOrario += " ";
}
testoFirmaPiccola = string.Empty;
thumbSizeSmall = new Size();
thumbSizeBig = new Size();
nomeFileSmall = string.Empty;
nomeFileBig2 = string.Empty;
nomeFileBig = string.Empty;
_dimensioneStandard = _picSettings.DimStandard;
_dimensioneStandardMiniatura = _picSettings.DimStandardMiniatura;
nomeFileSmall = _picSettings.Suffisso + WorkFile.Name;
nomeFileBig = WorkFile.Name;
}
private void PrepareThumbnailSize(Image g)
{
if (g.Width > g.Height)
{
thumbSizeSmall = NewthumbSize(g.Width, g.Height, CatalogVbLib.PicSettings.LarghezzaSmall, "Larghezza");
//Size sizeOrig = new Size(g.Width, g.Height);
//thumbSizeBig = sizeOrig;
thumbSizeBig = new Size(g.Width, g.Height);
}
else
{
thumbSizeSmall = NewthumbSize(g.Width, g.Height, CatalogVbLib.PicSettings.AltezzaSmall, "Altezza");
thumbSizeBig = new Size(g.Width, g.Height);
}
}
private void CreaMiniature(Image g, Bitmap imgOutputBig, ImageFormat thisFormat)
{
// CatalogLib.PicSettings ps = new PicSettings();
if (_picSettings.TestoMin)
{
testoFirmaPiccola = nomeFileBig;
}
else if (_picSettings.AggNumTempMin)
{
testoFirmaPiccola = nomeFileBig + " ";
}
Font crFont1;
Font crFont2;
SizeF crSize1 = new SizeF();
SizeF crSize2 = new SizeF();
if (_picSettings.CreaMiniature)
{
if (!_picSettings.AggiungiScritteMiniature)
{
if (string.Equals(_picSettings.DirectorySorgente, _picSettings.DirectoryDestinazione, StringComparison.CurrentCultureIgnoreCase))
{
nomeFileSmall = nomeFileSmall.Substring(0, nomeFileSmall.Length - 4) + _picSettings.Codice +
nomeFileSmall.Substring(nomeFileSmall.Length - 4);
}
if (_picSettings.UsaOrarioMiniatura ||
_picSettings.TestoMin ||
_picSettings.AggTempoGaraMin ||
_picSettings.AggNumTempMin)
{
if (!string.IsNullOrWhiteSpace(testoFirmaPiccola))
{
Bitmap imgOutputSmall = (Bitmap)imgOutputBig.Clone();
Graphics grPhoto1 = Graphics.FromImage(imgOutputSmall);
grPhoto1.SmoothingMode = SmoothingMode.HighSpeed; //Todo: permettere di cambiare questo parametro
int larghezzaStandard1;
_dimensioneStandardMiniatura = 50;
bool grassetto = _picSettings.Grassetto;
crFont1 = new Font(_picSettings.IlFont, _dimensioneStandardMiniatura, grassetto ? FontStyle.Bold : FontStyle.Regular);
crFont2 = new Font(_picSettings.IlFont, _dimensioneStandard, grassetto ? FontStyle.Bold : FontStyle.Regular);
crSize1 = grPhoto1.MeasureString(testoFirmaPiccola, crFont1);
crSize2 = grPhoto1.MeasureString(testoFirma, crFont1);
larghezzaStandard1 = (int)crSize1.Width;
if (crSize1.Width > g.Width)
{
int conta = _dimensioneStandardMiniatura;
do
{
if (conta > 20)
{
conta -= 5;
}
else
{
conta -= 1;
}
crFont1 = new Font(_picSettings.IlFont, conta, grassetto ? FontStyle.Bold : FontStyle.Regular);
crSize1 = grPhoto1.MeasureString(testoFirmaPiccola, crFont1);
if (crSize1.Width < g.Width)
{
larghezzaStandard1 = (int)crSize1.Width;
break;
}
} while (conta > 5);
_dimensioneStandardMiniatura = conta;
}
switch (_picSettings.TextPosition.ToString().ToUpper())
{
case "ALTO":
yPosFromBottom1 = _picSettings.Margine;
yPosFromBottom4 = _picSettings.MargVert;
break;
case "BASSO":
yPosFromBottom1 =
(float)
(g.Height - crSize1.Height - (g.Height * CatalogVbLib.PicSettings.Margine / 100));
yPosFromBottom4 = (float)(g.Height - crSize1.Height - (g.Height * CatalogVbLib.PicSettings.MargVert / 100));
break;
}
float xCenterOfImg1 = Single.NaN;
StringFormat strFormat1 = new StringFormat();
switch (_picSettings.Allineamento.ToUpper())
{
case "SINISTRA":
xCenterOfImg1 = CatalogVbLib.PicSettings.Margine + (larghezzaStandard1 / 2);
if ((larghezzaStandard1 / 2) > (g.Width / 2) - CatalogVbLib.PicSettings.Margine)
{
xCenterOfImg1 = g.Width / 2;
}
break;
case "CENTRO":
xCenterOfImg1 = (g.Width / 2);
break;
case "DESTRA":
xCenterOfImg1 = (g.Width - CatalogVbLib.PicSettings.Margine - (larghezzaStandard1 / 2));
if ((larghezzaStandard1 / 2) > (g.Width / 2) - CatalogVbLib.PicSettings.Margine)
{
xCenterOfImg1 = g.Width / 2;
}
break;
}
strFormat1.Alignment = StringAlignment.Center;
SolidBrush semiTransBrush21 = new SolidBrush(Color.FromArgb(alphaScelta, 0, 0, 0));
SolidBrush semiTransBrush1 = new SolidBrush(Color.FromArgb(alphaScelta, CatalogVbLib.PicSettings.fontColoreRGB));
_dimensioneStandardMiniatura = CatalogVbLib.PicSettings.DimMin;
if (_picSettings.Grassetto)
{
crFont1 = new Font(_picSettings.IlFont, _dimensioneStandardMiniatura, FontStyle.Bold);
}
else
{
crFont1 = new Font(_picSettings.IlFont, _dimensioneStandardMiniatura);
}
if (_picSettings.TestoMin)
{
grPhoto1.DrawString(nomeFileBig, crFont1, semiTransBrush21, new PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1), strFormat1);
grPhoto1.DrawString(nomeFileBig, crFont1, semiTransBrush1, new PointF(xCenterOfImg1, yPosFromBottom1), strFormat1);
}
else if (_picSettings.AggTempoGaraMin & _picSettings.UsaTempoGaraTestoApplicare)
{
//TimeSpan orario = (dataPartenzaI - dataFoto) * 10000000; //todo
TimeSpan orario = dataPartenzaI - dataFoto; //todo controllare se torna la roba giusta
string tempStr = "";
tempStr += Environment.NewLine + testoOrario + orario.Hours.ToString("00") + ":" +
orario.Minutes.ToString("00") + ":" + orario.Seconds.ToString("00"); //todo: usare una stringa formato per sta boiata
grPhoto1.DrawString(tempStr, crFont1, semiTransBrush21, new PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1));
grPhoto1.DrawString(tempStr, crFont1, semiTransBrush1, new PointF(xCenterOfImg1, yPosFromBottom1), strFormat1);
}
else if (_picSettings.AggNumTempMin) //todo semplificare la logica di sti eif
{
TimeSpan orario = dataPartenzaI - dataFoto; //todo controllare se torna la roba giusta
string tempStr = "";
tempStr += nomeFileBig + Environment.NewLine + testoOrario + orario.Hours.ToString("00") + ":" +
orario.Minutes.ToString("00") + ":" + orario.Seconds.ToString("00"); //todo: usare una stringa formato per sta boiata
grPhoto1.DrawString(tempStr, crFont1, semiTransBrush21, new PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1));
grPhoto1.DrawString(tempStr, crFont1, semiTransBrush1, new PointF(xCenterOfImg1, yPosFromBottom1), strFormat1);
}
else
{
grPhoto1.DrawString(testoFirmaPiccola, crFont1, semiTransBrush21, new PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1), strFormat1);
grPhoto1.DrawString(testoFirmaPiccola, crFont1, semiTransBrush1, new PointF(xCenterOfImg1, yPosFromBottom1), strFormat1);
}
//Salva miniatura
imgOutputSmall.Save(Path.Combine(DestDir.FullName, "Temp_" + nomeFileSmall), thisFormat);
float width = 0;
float height = 0;
//float scale = Math.Min(width/imgOutputSmall.Width, height/imgOutputSmall.Height);
using (var bmp = new Bitmap(thumbSizeSmall.Width, thumbSizeSmall.Height))
{
using (var graph = Graphics.FromImage(bmp))
{
// uncomment for higher quality output
//graph.InterpolationMode = InterpolationMode.High;
//graph.CompositingQuality = CompositingQuality.HighQuality;
//graph.SmoothingMode = SmoothingMode.AntiAlias;
graph.DrawImage(imgOutputSmall, new Rectangle(0, 0, (int)width, (int)height));
bmp.Save(Path.Combine(DestDir.FullName, nomeFileSmall), thisFormat);
}
}
//var bmp = new Bitmap(thumbSizeSmall.Width, thumbSizeSmall.Height);
//var graph = Graphics.FromImage(bmp);
// 10 down vote accepted
//Target parameters:
//float width = 1024;
//float height = 768;
//var brush = new SolidBrush(Color.Black);
//Your original file:
//var image = new Bitmap(file);
//Target sizing (scale factor):
//float scale = Math.Min(width / image.Width, height / image.Height);
//The resize including brushing canvas first:
//var bmp = new Bitmap((int)width, (int)height);
//var graph = Graphics.FromImage(bmp);
//// uncomment for higher quality output
////graph.InterpolationMode = InterpolationMode.High;
////graph.CompositingQuality = CompositingQuality.HighQuality;
////graph.SmoothingMode = SmoothingMode.AntiAlias;
//var scaleWidth = (int)(image.Width * scale);
//var scaleHeight = (int)(image.Height * scale);
//graph.FillRectangle(brush, new RectangleF(0, 0, width, height));
//graph.DrawImage(image, new Rectangle(((int)width - scaleWidth)/2, ((int)height - scaleHeight)/2, scaleWidth, scaleHeight));
//imgOutputSmall.Save(Path.Combine(DestDir.FullName, nomeFileSmall), thisFormat);
//Image g2 = Image.FromFile(Path.Combine(DestDir.FullName, "Temp_" + nomeFileSmall));
//Bitmap imgOutputSmall2 = new Bitmap(g2, thumbSizeSmall.Width, thumbSizeSmall.Height);
//imgOutputSmall2.Save(Path.Combine(DestDir.FullName, nomeFileSmall), thisFormat);
}
}
}
}
}
/// <summary>
/// Calculate the Size of the New image
/// </summary>
/// <param name="currentwidth">Larghezza</param>
/// <param name="currentheight">Altezza</param>
/// <param name="MaxPixel"></param>
/// <param name="TipoSize"></param>
/// <returns></returns>
/// <remarks></remarks>
private Size NewthumbSize(int currentwidth, int currentheight, int MaxPixel, string TipoSize)
{
// e
//*** Larghezza, Altezza, Auto
double tempMultiplier = 0;
if (TipoSize.ToUpper() == "Larghezza".ToUpper())
{
tempMultiplier = MaxPixel / currentwidth;
}
else if (TipoSize.ToUpper() == "Altezza".ToUpper())
{
tempMultiplier = MaxPixel / currentheight;
}
else
{
// portrait
if (currentheight > currentwidth)
{
tempMultiplier = MaxPixel / currentheight;
}
else
{
tempMultiplier = MaxPixel / currentwidth;
}
}
Size NewSize = new Size(Convert.ToInt32(currentwidth * tempMultiplier), Convert.ToInt32(currentheight * tempMultiplier));
return NewSize;
}
}
}

View file

@ -1,166 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CatalogVbLib;
namespace CatalogLib
{
public class ImageCreator2 : IImageProcessor
{
private PicSettings _picSettings = PicSettings.Instance;
private FileInfo _workFile;
private Image _workingImage;
private Rotazione _rotation;
private ImageFormat _currentFormat;
private Size _newImageSize;
private Bitmap _outputImage;
private DirectoryInfo _destDir;
private string _nomeFileBig;
public void Start(FileInfo workFile)
{
_workFile = workFile;
_workingImage = Image.FromFile(workFile.FullName);
_destDir = new DirectoryInfo(_picSettings.DirectoryDestinazione);
_nomeFileBig = _workFile.Name;
CalculateImageSize();
ElaborazioneTesto();
ElaborazioneRotazione();
SetImageFormat();
FinalElaboration();
//CreaMiniature
}
private void FinalElaboration()
{
_outputImage = new Bitmap(_workingImage, _newImageSize.Width, _newImageSize.Height);
_outputImage.SetResolution(_workingImage.HorizontalResolution, _workingImage.VerticalResolution);
SavePic(_outputImage, Path.Combine(_destDir.FullName, _nomeFileBig));
}
private void SavePic(Bitmap imageToSave, string fileName)
{
var selectedEncoder = GetEncoder(_currentFormat);
var encoder = System.Drawing.Imaging.Encoder.Quality;
var encoderParameters = new EncoderParameters(1);
if (Equals(_currentFormat, ImageFormat.Jpeg))
{
var encoderParameter = new EncoderParameter(encoder, _picSettings.CompressioneJpeg);
encoderParameters.Param[0] = encoderParameter;
}
imageToSave.Save(fileName, selectedEncoder,encoderParameters);
imageToSave.Dispose();
}
private ImageCodecInfo GetEncoder(ImageFormat format)
{
var codecs = ImageCodecInfo.GetImageDecoders();
return codecs.FirstOrDefault(c => c.FormatID == format.Guid);
}
private void ElaborazioneTesto()
{
if (_picSettings.EnableText)
{
// todo: elaborazione testo
}
}
private void CalculateImageSize()
{
_newImageSize = new Size(_workingImage.Width, _workingImage.Height);
}
private void ElaborazioneRotazione()
{
_rotation = Rotazione.Normale;
if (_picSettings.GeneraleRotazioneAutomatica)
{
// ci sono dati exif
if (_workingImage.PropertyIdList.Length > 0)
{
ExifReader DatiExif = new ExifReader((Bitmap)_workingImage);
switch (DatiExif.Orientation)
{
case ExifReader.Orientations.BottomLeft:
break;
case ExifReader.Orientations.BottomRight:
break;
case ExifReader.Orientations.LeftTop:
break;
case ExifReader.Orientations.LftBottom:
//FotoRuotaASinistra = true;
_rotation = Rotazione.Sinistra;
break;
case ExifReader.Orientations.RightBottom:
break;
case ExifReader.Orientations.RightTop:
break;
case ExifReader.Orientations.TopLeft:
break;
case ExifReader.Orientations.TopRight:
break;
}
}
}
if (_rotation == Rotazione.Sinistra)
{
_workingImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
}
else
if (_rotation == Rotazione.Destra)
{
_workingImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
}
}
private void SetImageFormat()
{
_currentFormat = _workingImage.RawFormat;
if (_picSettings.GeneraleForzaJPG)
{
_currentFormat = ImageFormat.Jpeg;
}
}
}
}

View file

@ -1,549 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;
using MaddoLibrary.Base.Log;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.MetaData.Profiles.Exif;
using SixLabors.ImageSharp.Processing;
using SixLabors.Primitives;
using Font = SixLabors.Fonts.Font;
using FontFamily = SixLabors.Fonts.FontFamily;
using FontStyle = SixLabors.Fonts.FontStyle;
using Rgba32 = SixLabors.ImageSharp.Rgba32;
using Image = SixLabors.ImageSharp.Image;
namespace CatalogLib
{
public class ImgSharpCreator : IImageProcessor
{
private Image<Rgba32> _logo;
public ImgSharpCreator()
{
if (!PicSettings.Instance.EnableLogo) return;
if (string.IsNullOrWhiteSpace(PicSettings.Instance.LogoPath)) return;
if (!File.Exists(PicSettings.Instance.LogoPath)) return;
_logo = Image.Load(PicSettings.Instance.LogoPath);
}
private FileInfo _currentFile;
public void Start(FileInfo workFile)
{
Stopwatch s = new Stopwatch();
s.Start();
_currentFile = workFile;
using (Image<Rgba32> image = Image.Load(workFile.FullName)/* new Image(workFile.FullName)*/)
{
MaddoLogger.Log("Loaded Image: {0}", workFile.FullName);
//image.Rotate(-90);
bool isRotated;
var orientation = image.MetaData.ExifProfile.GetValue(ExifTag.Orientation);
if ((ushort)orientation.Value != 1)
{
isRotated = true;
}
else
{
isRotated = false;
}
if (PicSettings.Instance.FotoRidimensiona)
{
Resize(image);
}
if (PicSettings.Instance.GeneraleRotazioneAutomatica)
{
image.Mutate(img => img.AutoOrient());
MaddoLogger.Log("Rotated Image: {0}", workFile.FullName);
//image.AutoOrient();
//var exif = image.MetaData.ExifProfile;
//if (exif != null)
//{
// var o = exif.GetValue(ExifTag.Orientation);
// if (o != null)
// {
// var v = (ushort)o.Value;
// switch (v)
// {
// //1 = Horizontal(normal)
// //2 = Mirror horizontal
// //3 = Rotate 180
// //4 = Mirror vertical
// //5 = Mirror horizontal and rotate 270 CW
// //6 = Rotate 90 CW
// //7 = Mirror horizontal and rotate 90 CW
// //8 = Rotate 270 CW
// case 1:
// break;
// case 2:
// image.Flip(FlipType.Horizontal);
// break;
// case 3:
// //image.Rotate(180f);
// //image.Rotate(90);
// image.Rotate(RotateType.Rotate180);
// break;
// case 4:
// image.Flip(FlipType.Vertical);
// break;
// case 5:
// image.RotateFlip(RotateType.Rotate270, FlipType.Horizontal);
// break;
// case 6:
// image.Rotate(RotateType.Rotate90);
// break;
// case 7:
// image.RotateFlip(RotateType.Rotate90, FlipType.Horizontal);
// break;
// case 8:
// //image.Rotate(-90);
// image.Rotate(RotateType.Rotate270);
// image.MetaData.ExifProfile.SetValue(ExifTag.Orientation, new ExifValue(exif.GetValue(ExifTag.Orientation)).Value = (ushort)1);
// break;
// }
// }
//}
}
if (PicSettings.Instance.EnableText)
{
//SetTextTest(image);
SetExtraText(image, isRotated);
MaddoLogger.Log("Drawn text on Image: {0}", workFile.FullName);
}
//JpegDecoder j = new JpegDecoder();
var va = Vector.IsHardwareAccelerated;
MaddoLogger.Log("Hardware Accelerated: {0}", va);
//image.Resize(PicSettings.Instance.FotoLarghezza, PicSettings.Instance.FotoAltezza);
//image.Resize(2240, 2240);
//var fff = FontCollection.SystemFonts.Find(PicSettings.Instance.NomeFont);
//var font = new Font(fff, (float)PicSettings.Instance.DimensioneFont, FontStyle.Regular);
//image.DrawText("sssssssssssssssssssssssssssssssssssssssssssssss", font, Color.Black, new Vector2(200, 200));
image.Save(Path.Combine(PicSettings.Instance.DirectoryDestinazione, workFile.Name), new JpegEncoder() { Quality = PicSettings.Instance.CompressioneJpeg });
//image.Resize(200, 200).Save("");
MaddoLogger.Log("Saved Image: {0} to: {1}", workFile.FullName, Path.Combine(PicSettings.Instance.DirectoryDestinazione, workFile.Name));
}
s.Stop();
MaddoLogger.Log("Time Taken for {0}: {1}", workFile.FullName, s.Elapsed);
}
private void Resize(Image<Rgba32> image)
{
IResampler resampler;
switch (PicSettings.Instance.ResizeMode)
{
case ResizeModes.Bicubic:
resampler = new BicubicResampler();
break;
case ResizeModes.Box:
resampler = new BoxResampler();
break;
case ResizeModes.CatmullRom:
resampler = new CatmullRomResampler();
break;
case ResizeModes.Hermite:
resampler = new HermiteResampler();
break;
case ResizeModes.Lanczos2:
resampler = new Lanczos2Resampler();
break;
case ResizeModes.Lanczos3:
resampler = new Lanczos3Resampler();
break;
case ResizeModes.Lanczos5:
resampler = new Lanczos5Resampler();
break;
case ResizeModes.Lanczos8:
resampler = new Lanczos8Resampler();
break;
case ResizeModes.MitchellNetravali:
resampler = new MitchellNetravaliResampler();
break;
case ResizeModes.NearestNeighbor:
resampler = new NearestNeighborResampler();
break;
case ResizeModes.Robidoux:
resampler = new RobidouxResampler();
break;
case ResizeModes.Spline:
resampler = new SplineResampler();
break;
case ResizeModes.Triangle:
resampler = new TriangleResampler();
break;
case ResizeModes.Welch:
resampler = new WelchResampler();
break;
default:
throw new ArgumentOutOfRangeException();
}
// todo calcolare ridimensionamento
var size = new Size(PicSettings.Instance.FotoLarghezza, PicSettings.Instance.FotoAltezza);
if (PicSettings.Instance.FotoMantieniDimensioni)
{
size = ResizeImage(image, size, PicSettings.Instance.ResizeDimension);
image.Mutate(x => x.Resize((size.Width), (size.Height), resampler));
//Width Formula:
//original height / original width * new width = new height
//Height Formula:
//orignal width / orignal height * new height = new width
}
else
{
image.Mutate(x => x.Resize(PicSettings.Instance.FotoAltezza, PicSettings.Instance.FotoLarghezza, resampler));
}
}
private Size ResizeImage(Image<Rgba32> image, Size size, ResizeDimensions side)
{
switch (side)
{
case ResizeDimensions.LatoLungo:
size = GetResizeDimensions(new Size(image.Width, image.Height), size, image.Width > image.Height);
break;
case ResizeDimensions.LatoCorto:
size = GetResizeDimensions(new Size(image.Width, image.Height), size, image.Width <= image.Height);
break;
default:
throw new ArgumentOutOfRangeException();
}
return size;
}
private Size GetResizeDimensions(Size originalSize, Size newSize, bool adjustHeight)
{
return adjustHeight ? new Size(newSize.Width, originalSize.Height / originalSize.Width * newSize.Height) : new Size(originalSize.Width / originalSize.Height * newSize.Height, newSize.Height);
}
private void SetTextTest(Image<Rgba32> image)
{
string text = "test test test test test testtest test test test test test test";
Font font = new Font(SystemFonts.Find("verdana"), 300, FontStyle.Regular);
image.Mutate(x => x.DrawText(text, font, Rgba32.Yellow, new PointF(2760, 3295.54932f), new TextGraphicsOptions()
{
HorizontalAlignment = HorizontalAlignment.Center
}));
}
private void SetExtraText(Image<Rgba32> image, bool isRotated)
{
if (string.IsNullOrWhiteSpace(PicSettings.Instance.TestoApplicareOrizzontale))
{
Debug.WriteLine($"{_currentFile.Name} No text");
return;
}
string text;
if (isRotated)
{
if (PicSettings.Instance.TestoApplicareOrizzontale.Contains("$_"))
{
text = PicSettings.Instance.TestoApplicareOrizzontale.Replace("$_", "\r\n");
}
else
{
text = PicSettings.Instance.TestoApplicareOrizzontale.Replace("$_", "");
}
}
else
{
text = PicSettings.Instance.TestoApplicareOrizzontale.Replace("$_", "");
}
var fo = SixLabors.Fonts.SystemFonts.Find(PicSettings.Instance.NomeFont);
//var fff = FontCollection.SystemFonts.Find(PicSettings.Instance.NomeFont);
//var fff = FontCollection.SystemFonts.Find("Segoe Print");
Font font;
if (!PicSettings.Instance.Grassetto)
{
font = new Font(fo, (float)PicSettings.Instance.DimensioneFont, FontStyle.Regular);
}
else
{
font = new Font(fo, (float)PicSettings.Instance.DimensioneFont, FontStyle.Bold);
}
// todo corsivo
//var font = new Font(fff, 8f, FontStyle.Regular);
//Color c = Color.FromHex(FlipRgbString(PicSettings.Instance.ColoreTestoRGB));
Rgba32 g = Rgba32.FromHex(FlipRgbString(PicSettings.Instance.ColoreTestoRGB));
Rgba32 gBack = Rgba32.Black; // todo alpha
//TextMeasurer measurer = new TextMeasurer();
//var size = measurer.MeasureText(PicSettings.Instance.TestoApplicareOrizzontale, font, 72);
//float scalingFactor = Math.Min(image.Width / size.Width, image.Height / size.Height);
//Font scaledFont = new Font(font, scalingFactor * font.Size);
//image.DrawText(PicSettings.Instance.TestoApplicareOrizzontale, scaledFont, g, new Vector2(0, 0));
Vector2 center = new Vector2(image.Width / 2, image.Height / 2); //center horizontally, 10px down
var size = TextMeasurer.Measure(text, new RendererOptions(font));
var larghezzaStandard = size.Width;
var dimensioneStandard = (int)Math.Round(PicSettings.Instance.DimensioneFont);
if (size.Width > image.Width)
{
var c = dimensioneStandard;
do
{
if (c > 20)
{
c -= 5;
}
else
{
c -= 1;
}
if (PicSettings.Instance.Grassetto)
{
font = new Font(fo, c, FontStyle.Bold);
}
else
{
font = new Font(fo, c, FontStyle.Regular);
}
size = TextMeasurer.Measure(text,
new RendererOptions(font));
if (size.Width < image.Width)
{
larghezzaStandard = (int)Math.Round(size.Width);
break;
}
if (c <= 5)
{
break;
}
} while (dimensioneStandard == c);
}
float yPosFromBottom = 0;
switch (PicSettings.Instance.TextPosition)
{
case Positions.Alto:
yPosFromBottom = PicSettings.Instance.Margine;
break;
case Positions.Basso:
yPosFromBottom = image.Height - size.Height - (image.Height * PicSettings.Instance.Margine / 100);
break;
}
float xCenterofImg = 0;
// stringformat
switch (PicSettings.Instance.TextAlignment)
{
case Alignments.Sinistra:
xCenterofImg = PicSettings.Instance.Margine + (larghezzaStandard / 2);
if ((larghezzaStandard / 2) > (image.Width / 2) - PicSettings.Instance.Margine)
{
xCenterofImg = image.Width / 2;
}
break;
case Alignments.Centro:
xCenterofImg = image.Width / 2;
break;
case Alignments.Destra:
xCenterofImg = image.Width - PicSettings.Instance.Margine - larghezzaStandard / 2;
if (larghezzaStandard / 2 > image.Width / 2 - PicSettings.Instance.Margine)
{
xCenterofImg = image.Width / 2;
}
break;
}
// stringformat alignment center
if (PicSettings.Instance.Grassetto)
{
font = new Font(fo, dimensioneStandard, FontStyle.Bold);
}
else
{
font = new Font(fo, dimensioneStandard, FontStyle.Regular);
}
image.Mutate(x => x.DrawText(text, font, gBack, new PointF((float)Math.Round(xCenterofImg + 1), (float)Math.Round(yPosFromBottom + 1)), new TextGraphicsOptions()
{
HorizontalAlignment = HorizontalAlignment.Center
}));
image.Mutate(x => x.DrawText(text, font, g, new PointF((float)Math.Round(xCenterofImg), (float)Math.Round(yPosFromBottom)), new TextGraphicsOptions()
{
HorizontalAlignment = HorizontalAlignment.Center
}));
return;
float scalingFactor = Math.Min(image.Width / size.Width, image.Height / size.Height);
Font scaledFont = new Font(font, scalingFactor * font.Size);
image.Mutate(x =>
x.DrawText(PicSettings.Instance.TestoApplicareOrizzontale, scaledFont, g, center,
new TextGraphicsOptions(true)
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Bottom
}));
//image.DrawText(PicSettings.Instance.TestoApplicareOrizzontale, scaledFont, g, center, new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Bottom });
}
private void AddLogo(Image<Rgba32> image)
{
//if (string.IsNullOrWhiteSpace(PicSettings.Instance.LogoPath)) return;
//if (!File.Exists(PicSettings.Instance.LogoPath)) return;
//using (Image<Rgba32> logo = Image.Load(PicSettings.Instance.LogoPath))
//{
// Size size = new Size();
// Point location = new Point();
// image.Mutate(x => x.DrawImage(logo, size, location, new GraphicsOptions()
// {
// }));
//}
Size size = new Size();
Point location = new Point();
if (_logo != null)
{
var width = PicSettings.Instance.LogoWidth;
var height = PicSettings.Instance.LogoHeight;
var heightFactor = _logo.Height / height;
var widthFactor = _logo.Width / width;
var newLogoSize = new Size();
newLogoSize = GetResizeDimensions(new Size(_logo.Width, _logo.Height), new Size(width, height), PicSettings.Instance.LogoResizeSide.Equals(ResizeDimensions.LatoCorto));
//todo riguardare perché non torna cosa ho fatto
int margineUsato = 0;
int margineL;
bool inPercentualeL;
inPercentualeL = PicSettings.Instance.LogoMargin.EndsWith("%");
if (inPercentualeL)
{
margineL = int.Parse(PicSettings.Instance.LogoMargin.Replace("%", ""));
}
else
{
margineL = int.Parse(PicSettings.Instance.LogoMargin);
}
switch (PicSettings.Instance.LogoPosition)
{
case Positions.Alto:
break;
case Positions.Centro:
break;
case Positions.Basso:
break;
default:
throw new ArgumentOutOfRangeException();
}
switch (PicSettings.Instance.LogoAlignment)
{
case Alignments.Sinistra:
location.X = margineUsato;
break;
case Alignments.Centro:
//location.X = image.Width -
break;
case Alignments.Destra:
break;
default:
throw new ArgumentOutOfRangeException();
}
image.Mutate(x => x.DrawImage(_logo, size, location, new GraphicsOptions()));
}
}
private void WriteTextFixed(Image<Rgba32> image)
{
var fo = SixLabors.Fonts.SystemFonts.Find("Microsoft Sans Serif");
var font = new Font(fo, 8, FontStyle.Regular);
Rgba32 g = Rgba32.FromHex("#FF00FFFF");
Vector2 center = new Vector2(image.Width / 2, image.Height / 2);
var size = TextMeasurer.Measure("Test test test test test", new RendererOptions(font));
float scalingFactor = Math.Min(image.Width / size.Width, image.Height / size.Height);
Font scaledFont = new Font(font, scalingFactor * font.Size);
image.Mutate(x => x.DrawText("Test test test test test", scaledFont, g, center, new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Bottom }));
}
private string FlipRgbString(string originalString)
{
string s;
if (originalString.Length == 7)
{
s = string.Concat("#", originalString.Substring(1, 6));
}
else
{
s = string.Concat("#", originalString.Substring(3, 6), originalString.Substring(1, 2));
}
return s;
}
}
}

View file

@ -1,548 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MaddoLibrary.Base.Log;
using Newtonsoft.Json;
namespace CatalogLib
{
public class PicSettings
{
private static PicSettings _instance = new PicSettings();
public static PicSettings Instance
{
get { return _instance; }
}
private Dictionary<string, object> _settingsDict = new Dictionary<string, object>();
public PicSettings()
{
SetDefaults();
}
public string SerializeSettings()
{
return JsonConvert.SerializeObject(_settingsDict);
}
public void DeserializeSettings(string serializedData)
{
_settingsDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(serializedData);
}
public void SetBase(string key, object value)
{
if (_settingsDict.ContainsKey(key))
{
_settingsDict[key] = value;
}
else
{
_settingsDict.Add(key, value);
}
}
public void SetString(string key, string value)
{
SetBase(key, value);
}
public void SetInt(string key, int value)
{
SetBase(key, value);
}
public void SetBool(string key, bool value)
{
SetBase(key, value);
}
public void SetDouble(string key, double value)
{
SetBase(key, value);
}
public void SetFloat(string key, float value)
{
SetBase(key, value);
}
public void Set<T>(string key, T value)
{
SetBase(key, value);
}
public bool Exists(string key)
{
return _settingsDict.ContainsKey(key);
}
public int GetInt(string key, int defaultValue = 0)
{
if (!_settingsDict.ContainsKey(key))
{
SetInt(key, defaultValue);
}
if (_settingsDict[key] is int) return (int)_settingsDict[key];
Debug.WriteLine($"Error while parsing {key}");
//return defaultValue;
int r;
if (int.TryParse(_settingsDict[key].ToString(), out r))
{
SetInt(key, r);
}
else
{
SetInt(key, defaultValue);
}
return (int)_settingsDict[key];
//return (int) _settingsDict[key];
//return _settingsDict.ContainsKey(key) ? (int)_settingsDict[key] : defaultValue;
}
public double GetDouble(string key, double defaultValue = 0)
{
if (!_settingsDict.ContainsKey(key))
{
SetDouble(key, defaultValue);
// setdouble default
}
if (_settingsDict[key] is double) return (double)_settingsDict[key];
Debug.WriteLine($"Error while parsing {key}");
double d;
if (double.TryParse(_settingsDict[key].ToString(), out d))
{
SetDouble(key, d);
// setdouble key r
}
else
{
SetDouble(key, defaultValue);
//setdouble defaultvalue
}
return (double)_settingsDict[key];
}
public float GetFloat(string key, float defaultValue = 0)
{
if (!_settingsDict.ContainsKey(key))
{
SetFloat(key, defaultValue);
}
if (_settingsDict[key] is float f) return f;
MaddoLogger.LogError("Error while parsing {0}", key);
float fl = 0;
SetFloat(key, float.TryParse(_settingsDict[key].ToString(), out f) ? fl : defaultValue);
return (float)_settingsDict[key];
}
public T Get<T>(string key, T defaultValue)
{
if (!_settingsDict.ContainsKey(key))
{
Set<T>(key, defaultValue);
// setdouble default
}
return (T)_settingsDict[key];
}
public string GetString(string key, string defaultValue = "")
{
if (!_settingsDict.ContainsKey(key))
{
SetString(key, defaultValue);
}
return (string)_settingsDict[key];
//return _settingsDict.ContainsKey(key) ? (string)_settingsDict[key] : defaultValue;
}
public bool GetBool(string key, bool defaultValue = false)
{
if (!_settingsDict.ContainsKey(key))
{
SetBool(key, defaultValue);
return defaultValue;
}
return (bool)_settingsDict[key];
//return _settingsDict.ContainsKey(key) && (bool)_settingsDict[key];
}
public object GetObject(string key, object defaultValue = null)
{
if (!_settingsDict.ContainsKey(key))
{
Set(key, defaultValue);
return defaultValue;
}
return _settingsDict[key];
//return _settingsDict.ContainsKey(key) ? _settingsDict[key] : defaultValue;
}
public T GetEnum<T>(string name, T defaultValue)
{
return (T)Enum.Parse(typeof(T), GetString(name, defaultValue.ToString()));
}
public void SetDefaults()
{
}
public bool DirAggiornaSottoDirectory
{
get => this.GetBool("DirAggiornaSottoDirectory", true);
set => this.SetBool("DirAggiornaSottoDirectory", value);
}
public bool Grassetto
{
get { return GetBool("Grassetto"); }
set { SetBool("Grassetto", value); }
}
public string IlFont //todo
{
get { return GetString(""); }
set { }
}
public bool TestoMin //todo
{
get { return false; }
set { }
}
public bool AggTempoGaraMin //todo
{
get { return false; }
set { }
}
public bool UsaTempoGaraTestoApplicare //todo
{
get { return false; }
set { }
}
public bool AggNumTempMin //todo
{
get { return false; }
set { }
}
public bool CreaMiniature //todo
{
get { return false; }
set { }
}
public bool AggiungiScritteMiniature
{
get { return false; }
set { }
}
public string Suffisso
{
get { return string.Empty; }
set { }
}
public string Codice
{
get { return null; }
set { }
}
public int Trasparenza
{
get { return 0; }
}
public DateTime DataPartenza { get; set; }
public string TestoOrario { get; internal set; }
public int DimStandard { get; internal set; }
public int DimStandardMiniatura { get; internal set; }
public bool UsaOrarioTestoApplicare { get; set; }
public bool UsaOrarioMiniatura { get; set; }
public string TestoFirmaStart { get; set; }
public string TestoFirmaStartV { get; set; }
public bool UsaForzaJpg { get; set; }
public string DirectorySorgente
{
get { return GetString("DirSorgente"); }
set { SetString("DirSorgente", value); }
}
public string DirectoryDestinazione
{
get { return GetString("DirDestinazione"); }
set { SetString("DirDestinazione", value); }
}
public int Margine
{
get => GetInt("Margin", 1);
set => SetInt("Margin", value);
}
public float MargVert { get; set; }
public string Allineamento { get; set; }
public bool GeneraleForzaJPG
{
get { return GetBool("GeneraleForzaJPG", true); }
set { SetBool("GeneraleForzaJPG", value); }
}
public bool GeneraleRotazioneAutomatica
{
get { return GetBool("GeneraleRotazioneAutomatica", true); }
set { SetBool("GeneraleRotazioneAutomatica", value); }
}
public bool GeneraleSovrascriviFile
{
get { return GetBool("GeneraleSovrascriviFile"); }
set { SetBool("GeneraleSovrascriviFile", value); }
}
public bool SubdirCreaSottoCartelle
{
get { return GetBool("SubdirCreaSottoCartelle"); }
set { SetBool("SubdirCreaSottoCartelle", value); }
}
public int SubdirIntervalloFile
{
get { return GetInt("SubdirIntervalloFile", 99); }
set { SetInt("SubdirIntervalloFile", value); }
}
public string SubdirSuffisso
{
get { return GetString("SubdirSuffisso"); }
set { SetString("SubdirSuffisso", value); }
}
public int SubdirCifreContatore
{
get { return GetInt("SubdirCifreContatore", 2); }
set { SetInt("SubdirCifreContatore", value); }
}
public bool SubdirNumerazioneProgressiva
{
get { return GetBool("SubdirNumerazioneProgressiva", true); }
set { SetBool("SubdirNumerazioneProgressiva", value); }
}
public bool SubdirNumerazioneFiles
{
get { return GetBool("SubdirNumerazioneFiles", false); }
set { SetBool("SubdirNumerazioneFiles", value); }
}
public int FotoAltezza
{
get { return GetInt("FotoAltezza", 2240); }
set { SetInt("FotoAltezza", value); }
}
public int FotoLarghezza
{
get { return GetInt("FotoLarghezza", 2240); }
set { SetInt("FotoLarghezza", value); }
}
public int CompressioneJpeg
{
get { return GetInt("CompressioneJpeg", 85); }
set { SetInt("CompressioneJpeg", value); }
}
public bool FotoMantieniDimensioni
{
get { return GetBool("FotoMantieniDimensioni", true); }
set { SetBool("FotoMantieniDimensioni", value); }
}
public string FotoSuffisso
{
get { return GetString("FotoSuffisso"); }
set { SetString("FotoSuffisso", value); }
}
public bool EnableThumbnails
{
get { return GetBool("EnableThumbnails", false); }
set { SetBool("EnableThumbnails", value); }
}
public bool EnableLogo
{
get { return GetBool("EnableLogo", false); }
set { SetBool("EnableLogo", value); }
}
#region Text
public bool EnableText
{
get { return GetBool("EnableText", false); }
set { SetBool("EnableText", value); }
}
public string NomeFont
{
get { return GetString("nomeFont", "Verdana"); }
set { SetString("nomeFont", value); }
}
public double DimensioneFont
{
get { return Get<double>("dimensioneFont", 1); }
set { SetDouble("dimensioneFont", value); }
}
public string TestoApplicareOrizzontale
{
get
{
return Get<string>("TestoApplicareOrizzontale", "");
}
set
{
Set<string>("TestoApplicareOrizzontale", value);
}
}
public string ColoreTestoRGB
{
get { return GetString("coloreTestoRGB", "#000000"); }
set
{
Set("coloreTestoRGB", value);
}
}
public bool FotoRidimensiona
{
get => GetBool("FotoRidimensiona", false);
set => Set("FotoRidimensiona", value);
}
public Positions TextPosition
{
get => GetEnum("TextPosition", Positions.Alto); //(Positions)Enum.Parse(typeof(Positions), GetString("TextPosition", Positions.Alto.ToString()));
set => SetString("TextPosition", value.ToString());
}
public Alignments TextAlignment
{
get => GetEnum("TextAlignment", Alignments.Centro);
set => SetString("TextAlignment", value.ToString());
}
public bool Threading
{
get => GetBool("Threading", true);
set => SetBool("Threading", value);
}
public ResizeModes ResizeMode
{
get => GetEnum("ResizeMode", ResizeModes.Bicubic);
set => SetString("ResizeMode", value.ToString());
}
public ResizeDimensions ResizeDimension
{
get => GetEnum("ResizeDimension", CatalogLib.ResizeDimensions.LatoCorto);
set => SetString("ResizeDimension", value.ToString());
}
public string LogoPath
{
get => GetString("LogoPath");
set => SetString("LogoPath", value);
}
public int LogoWidth
{
get => GetInt("LogoWidth");
set => SetInt("LogoWidth", value);
}
public int LogoHeight
{
get => GetInt("LogoHeight");
set => SetInt("LogoHeight", value);
}
public string LogoMargin
{
get => GetString("LogoMargin");
set => SetString("LogoMargin", value);
}
public Positions LogoPosition
{
get => GetEnum("LogoPositions", Positions.Alto);
set => SetString("LogoPositions", value.ToString());
}
public Alignments LogoAlignment
{
get => GetEnum("LogoAlignments", Alignments.Centro);
set => SetString("LogoAlignments", value.ToString());
}
public ResizeDimensions LogoResizeSide
{
get => GetEnum("LogoResizeMode", ResizeDimensions.LatoCorto);
set => SetString("LogoResizeMode", value.ToString());
}
#endregion
#region Enums
#endregion
}
}

View file

@ -1,38 +0,0 @@
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CatalogLib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CatalogLib")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7bb8e6ce-72c8-4b36-a166-a62ed446d4e9")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: CLSCompliant(true)]

View file

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CatalogLib
{
public enum Rotazione
{
Normale,
Destra,
Sinistra,
Sottosopra
}
public class SinglePicData
{
}
}

View file

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>

View file

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ImageSharp" version="1.0.0-alpha9-00169" targetFramework="net46" />
<package id="ImageSharp.Drawing" version="1.0.0-alpha9-00164" targetFramework="net46" />
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net46" />
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net46" />
<package id="NETStandard.Library" version="1.6.1" targetFramework="net46" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net46" />
<package id="SixLabors.Core" version="0.1.0-alpha0002" targetFramework="net46" />
<package id="SixLabors.Fonts" version="0.1.0-alpha0014" targetFramework="net46" />
<package id="SixLabors.Shapes" version="0.1.0-alpha0018" targetFramework="net46" />
<package id="SixLabors.Shapes.Text" version="0.1.0-alpha0018" targetFramework="net46" />
<package id="System.AppContext" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Buffers" version="4.3.0" targetFramework="net46" />
<package id="System.Collections" version="4.3.0" targetFramework="net46" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net46" />
<package id="System.Collections.Immutable" version="1.3.1" targetFramework="net46" />
<package id="System.Console" version="4.3.0" targetFramework="net46" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net46" />
<package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net46" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net46" />
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Globalization" version="4.3.0" targetFramework="net46" />
<package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net46" />
<package id="System.IO" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net46" />
<package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net46" />
<package id="System.IO.FileSystem" version="4.3.0" targetFramework="net46" />
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net46" />
<package id="System.Linq" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Memory" version="4.4.0-preview1-25305-02" targetFramework="net46" requireReinstallation="true" />
<package id="System.Net.Http" version="4.3.0" targetFramework="net46" />
<package id="System.Net.Primitives" version="4.3.0" targetFramework="net46" />
<package id="System.Net.Sockets" version="4.3.0" targetFramework="net46" />
<package id="System.Numerics.Vectors" version="4.3.0" targetFramework="net46" />
<package id="System.ObjectModel" version="4.3.0" targetFramework="net46" />
<package id="System.Reflection" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net46" />
<package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net46" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net46" />
<package id="System.Runtime" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.4.0-preview1-25305-02" targetFramework="net46" requireReinstallation="true" />
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Runtime.Handles" version="4.3.0" targetFramework="net46" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net46" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net46" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net46" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net46" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net46" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net46" />
<package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net46" requireReinstallation="true" />
<package id="System.Threading" version="4.3.0" targetFramework="net46" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net46" />
<package id="System.Threading.Tasks.Parallel" version="4.3.0" targetFramework="net46" />
<package id="System.Threading.Timer" version="4.3.0" targetFramework="net46" />
<package id="System.ValueTuple" version="4.4.0-preview1-25305-02" targetFramework="net46" requireReinstallation="true" />
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net46" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net46" />
</packages>

View file

@ -1,15 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings":
{
"orderingRules":
{
"usingDirectivesPlacement": "outsideNamespace"
},
"documentationRules":
{
"xmlHeader": false,
"copyrightText": "Copyright (c) Six Labors and contributors.\nLicensed under the Apache License, Version 2.0."
}
}
}

View file

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B3352D87-BF9F-4F7A-9162-007492DA76E4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CatalogLibVb</RootNamespace>
<AssemblyName>CatalogLibVb</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CatalogLibVb
{
public class Class1
{
}
}

View file

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Le informazioni generali relative a un assembly sono controllate dal seguente
// set di attributi. Per modificare le informazioni associate a un assembly
// occorre quindi modificare i valori di questi attributi.
[assembly: AssemblyTitle("CatalogLibVb")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CatalogLibVb")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili
// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da
// COM, impostare su true l'attributo ComVisible per tale tipo.
[assembly: ComVisible(false)]
// Se il progetto viene esposto a COM, il GUID che segue verrà utilizzato per creare l'ID della libreria dei tipi
[assembly: Guid("367f3879-584c-4780-8ad0-dc84d2e77928")]
// Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori:
//
// Numero di versione principale
// Numero di versione secondario
// Numero build
// Revisione
//
// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build
// utilizzando l'asterisco (*) come descritto di seguito:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

41
CatalogLite/App.axaml Normal file
View file

@ -0,0 +1,41 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="CatalogLite.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="AppBackgroundBrush">#F4F6F8</SolidColorBrush>
<SolidColorBrush x:Key="PanelBackgroundBrush">#FFFFFF</SolidColorBrush>
<SolidColorBrush x:Key="BorderMutedBrush">#D4DAE2</SolidColorBrush>
<SolidColorBrush x:Key="AccentBrush">#1F7A5A</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="AppBackgroundBrush">#20242A</SolidColorBrush>
<SolidColorBrush x:Key="PanelBackgroundBrush">#2A3038</SolidColorBrush>
<SolidColorBrush x:Key="BorderMutedBrush">#46505C</SolidColorBrush>
<SolidColorBrush x:Key="AccentBrush">#4FB286</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Application.Resources>
<Application.Styles>
<FluentTheme DensityStyle="Compact" />
<Style Selector="Window">
<Setter Property="Background" Value="{DynamicResource AppBackgroundBrush}" />
</Style>
<Style Selector="Button">
<Setter Property="MinHeight" Value="34" />
<Setter Property="Padding" Value="12,5" />
</Style>
<Style Selector="TextBox">
<Setter Property="MinHeight" Value="34" />
<Setter Property="Padding" Value="8,5" />
</Style>
<Style Selector="ProgressBar">
<Setter Property="MinHeight" Value="18" />
</Style>
<StyleInclude Source="avares://IconPacks.Avalonia.Material/Material.axaml" />
</Application.Styles>
</Application>

29
CatalogLite/App.axaml.cs Normal file
View file

@ -0,0 +1,29 @@
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Microsoft.Extensions.DependencyInjection;
namespace CatalogLite;
public partial class App : Avalonia.Application
{
public override void Initialize() => AvaloniaXamlLoader.Load(this);
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
if (ExpirationGuard.IsExpired(out var expirationDate))
{
var expiredWindow = new ExpiredWindow(expirationDate);
expiredWindow.Closed += (_, _) => desktop.Shutdown();
desktop.MainWindow = expiredWindow;
}
else
{
desktop.MainWindow = Program.ServiceProvider.GetRequiredService<MainWindow>();
}
}
base.OnFrameworkInitializationCompleted();
}
}

View file

@ -0,0 +1,42 @@
using System.Windows.Input;
namespace CatalogLite;
public sealed class AsyncCommand : ICommand
{
private readonly Func<Task> _execute;
private readonly Func<bool>? _canExecute;
private bool _isExecuting;
public AsyncCommand(Func<Task> execute, Func<bool>? canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public event EventHandler? CanExecuteChanged;
public bool CanExecute(object? parameter) => !_isExecuting && (_canExecute?.Invoke() ?? true);
public async void Execute(object? parameter)
{
if (!CanExecute(parameter))
{
return;
}
try
{
_isExecuting = true;
RaiseCanExecuteChanged();
await _execute().ConfigureAwait(false);
}
finally
{
_isExecuting = false;
RaiseCanExecuteChanged();
}
}
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

View file

@ -0,0 +1,269 @@
using System.Globalization;
using System.Xml.Linq;
using MaddoShared;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
namespace CatalogLite;
public sealed class CatalogConfigurationLoader
{
public CatalogLiteConfiguration Load(string filePath, PicSettings picSettings)
{
if (string.IsNullOrWhiteSpace(filePath))
{
throw new ArgumentException("Percorso configurazione non valido.", nameof(filePath));
}
if (!File.Exists(filePath))
{
throw new FileNotFoundException("File configurazione non trovato.", filePath);
}
var values = ConfigurationValues.Load(filePath);
ApplyPicSettings(values, picSettings);
var sourcePath = LiteCatalogViewModel.NormalizeDirectoryPath(values.GetString("DirSorgente"));
var destinationPath = LiteCatalogViewModel.NormalizeDirectoryPath(values.GetString("DirDestinazione"));
picSettings.DirectorySorgente = sourcePath;
picSettings.DirectoryDestinazione = destinationPath;
picSettings.DestDir = string.IsNullOrWhiteSpace(destinationPath)
? new DirectoryInfo(Environment.CurrentDirectory)
: new DirectoryInfo(destinationPath);
return new CatalogLiteConfiguration
{
FilePath = filePath,
SourcePath = sourcePath,
DestinationPath = destinationPath,
Options = BuildOptions(values, sourcePath, destinationPath)
};
}
public static ImageCreationService.Options CloneOptions(ImageCreationService.Options options, string sourcePath, string destinationPath)
{
return new ImageCreationService.Options
{
AggiornaSottodirectory = options.AggiornaSottodirectory,
CreaSottocartelle = options.CreaSottocartelle,
FilePerCartella = options.FilePerCartella,
SuffissoCartelle = options.SuffissoCartelle,
CifreContatore = options.CifreContatore,
NumerazioneType = options.NumerazioneType,
SourcePath = sourcePath,
DestinationPath = destinationPath,
MaxThreads = Math.Max(1, options.MaxThreads),
ChunksSize = options.ChunksSize,
LinearExecution = options.LinearExecution
};
}
private static void ApplyPicSettings(ConfigurationValues values, PicSettings settings)
{
settings.DirectorySorgente = values.GetString("DirSorgente");
settings.DirectoryDestinazione = values.GetString("DirDestinazione");
settings.TestoFirmaStart = values.GetString("TestoTesto");
settings.TestoFirmaStartV = values.GetString("TestoVerticale");
settings.DataPartenza = values.GetDateTime("DataPartenza", DateTime.Now);
settings.TestoOrario = values.GetString("EtichettaOrario");
settings.DimStandard = values.GetInt("FontDimensione", 20);
settings.DimStandardMiniatura = values.GetInt("FontDimensioneMiniatura", 50);
settings.NomeData = values.GetBool("DataFoto");
settings.TestoNome = values.GetBool("NumeroFoto");
settings.UsaOrarioMiniatura = IsThumbnailMode(values, "Time") || values.GetBool("MiniatureAddOrario");
settings.UsaOrarioTestoApplicare = values.GetBool("Orario");
settings.UsaTempoGaraTestoApplicare = values.GetBool("TempoGara");
settings.UsaRotazioneAutomatica = values.GetBool("GeneraleRotazioneAutomatica");
settings.UsaForzaJpg = values.GetBool("GeneraleForzaJpg");
settings.LarghezzaSmall = values.GetInt("MiniatureLarghezza", 350);
settings.AltezzaSmall = values.GetInt("MiniatureAltezza", 350);
settings.CreaMiniature = values.GetBool("MiniatureCrea", true);
settings.AggiungiScritteMiniature = IsThumbnailMode(values, "Text") || values.GetBool("MiniatureAddScritta");
settings.Suffisso = values.GetString("MiniatureSuffisso", "tn_");
settings.Codice = values.GetString("FotoCodice");
settings.Trasparenza = values.GetInt("TestoTrasparente", 0);
settings.IlFont = values.GetString("FontNome", "Arial");
settings.Grassetto = values.GetBool("FontBold");
settings.Posizione = values.GetString("TestoPosizione", "Basso");
settings.Allineamento = values.GetString("TestoAllineamento", "Centro");
settings.Margine = values.GetInt("TestoMargine", 8);
settings.LogoAltezza = values.GetInt("MarchioAltezza", 430);
settings.LogoLarghezza = values.GetInt("MarchioLarghezza", 430);
settings.FontColoreRGB = ParseColor(values.GetString("ColoreTestoRGB", "Yellow"), new Rgba32(255, 255, 0, 255));
settings.LogoAggiungi = values.GetBool("MarchioAggiungi");
settings.LogoNomeFile = values.GetString("MarchioFile");
settings.LogoTrasparenza = values.GetInt("MarchioTrasparenza", 100).ToString(CultureInfo.InvariantCulture);
settings.LogoMargine = values.GetString("MarchioMargine", "0");
settings.LogoPosizioneH = values.GetString("MarchioAllOrizzontale", "Destra");
settings.LogoPosizioneV = values.GetString("MarchioAllVerticale", "Basso");
settings.TransparentColor = values.GetString("ColoreTrasparente", "#FFFFFF");
settings.UseTransparentColor = values.GetBool("UsaColoreTrasparente");
settings.FotoGrandeDimOrigina = values.GetBool("FotoDimOriginali");
settings.AltezzaBig = values.GetInt("FotoAltezza", 2240);
settings.LarghezzaBig = values.GetInt("FotoLarghezza", 2240);
settings.DimVert = values.GetInt("GrandezzaVerticale", 20);
settings.MargVert = values.GetInt("MargineVerticale", 6);
settings.TestoMin = IsThumbnailMode(values, "FileName") || values.GetBool("NomeMiniatura");
settings.DimMin = values.GetInt("FontDimensioneMiniatura", 50);
settings.SecretDefault = false;
settings.SecretBig = false;
settings.SecretSmall = false;
settings.SecretPathSmall = string.Empty;
settings.SecretPathBig = string.Empty;
settings.AggTempoGaraMin = IsThumbnailMode(values, "RaceTime") || values.GetBool("TempoSmall");
settings.AggNumTempMin = IsThumbnailMode(values, "FileNameAndTime") || values.GetBool("NumTempoSmall");
settings.JpegQuality = values.GetLong("CompressioneJpeg", 85);
settings.JpegQualityMin = values.GetLong("CompressioneJpegMiniatura", 30);
settings.FotoRuotaADestra = false;
settings.FotoRuotaASinistra = false;
settings.TempMinText = string.Empty;
settings.OverwriteFiles = values.GetBool("GeneraleSovrascriviFile");
}
private static ImageCreationService.Options BuildOptions(ConfigurationValues values, string sourcePath, string destinationPath)
{
var threads = values.GetInt("ThreadsCount", Environment.ProcessorCount);
if (threads <= 0)
{
threads = Environment.ProcessorCount;
}
return new ImageCreationService.Options
{
AggiornaSottodirectory = values.GetBool("DirSottoDirectory"),
CreaSottocartelle = values.GetBool("DirCreaSottocartelle", values.GetBool("CreateSubfolders")),
FilePerCartella = Math.Max(1, values.GetInt("DirDividiNumFile", 99)),
SuffissoCartelle = values.GetString("DirDividiSuffisso"),
CifreContatore = Math.Max(1, values.GetInt("DirDividiNumCifre", 2)),
NumerazioneType = values.GetBool("DirNumerazioneProgressiva", true) ? NumerazioneType.Progressiva : NumerazioneType.Files,
SourcePath = sourcePath,
DestinationPath = destinationPath,
MaxThreads = Math.Max(1, threads),
ChunksSize = Math.Max(0, values.GetInt("ChunkSize", 0)),
LinearExecution = values.GetBool("UseSequentialProcessing")
};
}
private static bool IsThumbnailMode(ConfigurationValues values, string mode)
{
return string.Equals(values.GetString("MiniatureModalita"), mode, StringComparison.OrdinalIgnoreCase);
}
private static Rgba32 ParseColor(string value, Rgba32 fallback)
{
if (string.IsNullOrWhiteSpace(value))
{
return fallback;
}
var normalized = value.Trim();
try
{
if (normalized.StartsWith('#') && normalized.Length == 7)
{
return new Rgba32(
Convert.ToByte(normalized[1..3], 16),
Convert.ToByte(normalized[3..5], 16),
Convert.ToByte(normalized[5..7], 16),
255);
}
if (normalized.Length == 6 && normalized.All(Uri.IsHexDigit))
{
normalized = "#" + normalized;
}
return Color.Parse(normalized).ToPixel<Rgba32>();
}
catch
{
return fallback;
}
}
private sealed class ConfigurationValues
{
private readonly Dictionary<string, string> _values;
private ConfigurationValues(Dictionary<string, string> values)
{
_values = values;
}
public static ConfigurationValues Load(string filePath)
{
var document = XDocument.Load(filePath);
var values = document
.Descendants("Setup")
.Where(element => element.Element("Nome") is not null)
.GroupBy(element => element.Element("Nome")!.Value, StringComparer.OrdinalIgnoreCase)
.ToDictionary(
group => group.Key,
group => group.Last().Element("Valore")?.Value ?? string.Empty,
StringComparer.OrdinalIgnoreCase);
if (values.Count == 0)
{
values = document.Root?
.Descendants()
.Where(element => !element.HasElements)
.GroupBy(element => element.Name.LocalName, StringComparer.OrdinalIgnoreCase)
.ToDictionary(group => group.Key, group => group.Last().Value, StringComparer.OrdinalIgnoreCase)
?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
return new ConfigurationValues(values);
}
public string GetString(string name, string defaultValue = "")
{
return _values.TryGetValue(name, out var value) && !string.IsNullOrWhiteSpace(value)
? value.Trim()
: defaultValue;
}
public bool GetBool(string name, bool defaultValue = false)
{
var value = GetString(name);
if (string.IsNullOrWhiteSpace(value))
{
return defaultValue;
}
return value.Trim().ToUpperInvariant() switch
{
"TRUE" or "OK" or "SI" or "SÌ" or "1" or "YES" or "VERO" => true,
"FALSE" or "NO" or "0" or "FALSO" => false,
_ => defaultValue
};
}
public int GetInt(string name, int defaultValue = 0)
{
return int.TryParse(GetString(name), NumberStyles.Integer, CultureInfo.InvariantCulture, out var value)
? value
: defaultValue;
}
public long GetLong(string name, long defaultValue = 0)
{
return long.TryParse(GetString(name), NumberStyles.Integer, CultureInfo.InvariantCulture, out var value)
? value
: defaultValue;
}
public DateTime GetDateTime(string name, DateTime defaultValue)
{
var value = GetString(name);
if (DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var invariantDate))
{
return invariantDate;
}
return DateTime.TryParse(value, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out var localDate)
? localDate
: defaultValue;
}
}
}

View file

@ -0,0 +1,76 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<OutputType>Exe</OutputType>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AssemblyName>CatalogLite</AssemblyName>
<RootNamespace>CatalogLite</RootNamespace>
<AvaloniaUseCompiledBindingsByDefault>false</AvaloniaUseCompiledBindingsByDefault>
<CatalogLiteExpirationDate Condition="'$(CatalogLiteExpirationDate)' == ''">2026-12-31</CatalogLiteExpirationDate>
<UseAppHost>true</UseAppHost>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<PublishTrimmed>false</PublishTrimmed>
<PublishReadyToRun>false</PublishReadyToRun>
<DebugType>embedded</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'win-x64' Or '$(RuntimeIdentifier)' == 'win-arm64'">
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(IntermediateOutputPath)CatalogLiteExpiration.g.cs" Visible="false" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MaddoShared\MaddoShared.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.3.13" />
<PackageReference Include="Avalonia.Desktop" Version="11.3.13" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.13" />
<PackageReference Include="IconPacks.Avalonia.Material" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.8" />
</ItemGroup>
<Target Name="ValidateCatalogLiteExpirationDate" BeforeTargets="BeforeCompile">
<PropertyGroup>
<_CatalogLiteExpirationDateIsIso>$([System.Text.RegularExpressions.Regex]::IsMatch('$(CatalogLiteExpirationDate)', '^\d{4}-\d{2}-\d{2}$'))</_CatalogLiteExpirationDateIsIso>
</PropertyGroup>
<Error Condition="'$(_CatalogLiteExpirationDateIsIso)' != 'True'" Text="CatalogLiteExpirationDate must use yyyy-MM-dd format. Current value: $(CatalogLiteExpirationDate)" />
</Target>
<Target Name="GenerateCatalogLiteExpirationSource" BeforeTargets="CoreCompile" DependsOnTargets="ValidateCatalogLiteExpirationDate">
<WriteLinesToFile
File="$(IntermediateOutputPath)CatalogLiteExpiration.g.cs"
Overwrite="true"
Lines="using System.Reflection%3B&#x0A;&#x0A;[assembly: AssemblyMetadata(&quot;CatalogLiteGeneratedExpirationDate&quot;, &quot;$(CatalogLiteExpirationDate)&quot;)]&#x0A;[assembly: AssemblyMetadata(&quot;CatalogLiteExpirationDate&quot;, &quot;$(CatalogLiteExpirationDate)&quot;)]&#x0A;&#x0A;namespace CatalogLite%3B&#x0A;&#x0A;internal static class BuildExpiration&#x0A;{&#x0A; public const string ExpirationDate = &quot;$(CatalogLiteExpirationDate)&quot;%3B&#x0A;}" />
</Target>
<Target Name="ValidateCatalogLiteFeatureDependencies" AfterTargets="ResolveReferences">
<ItemGroup>
<_CatalogLiteForbiddenReference Include="@(ReferencePath)" Condition="$([System.String]::Copy('%(FileName)').StartsWith('AIFotoONLUS')) Or '%(FileName)' == 'Catalog.Communication' Or '%(FileName)' == 'Microsoft.Windows.Compatibility' Or '%(FileName)' == 'System.Drawing.Common' Or '%(FileName)' == 'System.Private.Windows.GdiPlus' Or '%(FileName)' == 'System.Windows.Extensions'" />
</ItemGroup>
<Error Condition="'@(_CatalogLiteForbiddenReference)' != ''" Text="Catalog Lite must not reference AI or race upload assemblies: @(_CatalogLiteForbiddenReference->'%(FileName)%(Extension)', ', ')" />
</Target>
<Target Name="PruneCatalogLitePublishSidecars" AfterTargets="Publish" Condition="'$(PublishDir)' != '' And '$(PublishSingleFile)' == 'true'">
<ItemGroup>
<_CatalogLiteSidecarFile Include="$(PublishDir)**\*.dll.config;$(PublishDir)**\*.pdb" />
</ItemGroup>
<Delete Files="@(_CatalogLiteSidecarFile)" />
</Target>
<Target Name="ValidateCatalogLitePublishOutput" AfterTargets="PruneCatalogLitePublishSidecars" Condition="'$(PublishDir)' != '' And '$(PublishSingleFile)' == 'true'">
<ItemGroup>
<_CatalogLiteLooseNativeFile Include="$(PublishDir)**\*.dll;$(PublishDir)**\*.so;$(PublishDir)**\*.dylib" />
</ItemGroup>
<Error Condition="'@(_CatalogLiteLooseNativeFile)' != ''" Text="Catalog Lite single-file publish produced loose native/managed library files: @(_CatalogLiteLooseNativeFile->'%(Filename)%(Extension)', ', ')" />
</Target>
</Project>

View file

@ -0,0 +1,11 @@
using MaddoShared;
namespace CatalogLite;
public sealed class CatalogLiteConfiguration
{
public required string FilePath { get; init; }
public required string SourcePath { get; init; }
public required string DestinationPath { get; init; }
public required ImageCreationService.Options Options { get; init; }
}

View file

@ -0,0 +1,39 @@
using System.Globalization;
using System.Reflection;
namespace CatalogLite;
internal static class ExpirationGuard
{
private const string GeneratedMetadataKey = "CatalogLiteGeneratedExpirationDate";
private const string MetadataKey = "CatalogLiteExpirationDate";
public static bool IsExpired(out DateOnly? expirationDate)
{
expirationDate = TryReadExpirationDate();
return expirationDate is null || DateOnly.FromDateTime(DateTime.Now) > expirationDate.Value;
}
private static DateOnly? TryReadExpirationDate()
{
if (TryParseDate(BuildExpiration.ExpirationDate, out var generatedDate))
{
return generatedDate;
}
var metadata = typeof(Program).Assembly.GetCustomAttributes<AssemblyMetadataAttribute>();
var metadataValue = metadata.FirstOrDefault(attribute => string.Equals(attribute.Key, GeneratedMetadataKey, StringComparison.Ordinal))?.Value
?? metadata.FirstOrDefault(attribute => string.Equals(attribute.Key, MetadataKey, StringComparison.Ordinal))?.Value;
return TryParseDate(metadataValue, out var metadataDate)
? metadataDate
: null;
}
private static bool TryParseDate(string? value, out DateOnly date)
{
var trimmedValue = value?.Trim();
return DateOnly.TryParseExact(trimmedValue, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out date)
|| DateOnly.TryParse(trimmedValue, CultureInfo.CurrentCulture, DateTimeStyles.None, out date);
}
}

View file

@ -0,0 +1,52 @@
using Avalonia.Controls;
using Avalonia.Layout;
namespace CatalogLite;
internal sealed class ExpiredWindow : Window
{
public ExpiredWindow(DateOnly? expirationDate)
{
Title = "Catalog Lite";
Width = 430;
Height = 190;
CanResize = false;
WindowStartupLocation = WindowStartupLocation.CenterScreen;
var message = expirationDate is null
? "L'applicazione è scaduta e non può essere utilizzata."
: $"L'applicazione è scaduta il {expirationDate:dd/MM/yyyy} e non può essere utilizzata.";
var closeButton = new Button
{
Content = "Chiudi",
HorizontalAlignment = HorizontalAlignment.Right,
MinWidth = 96
};
closeButton.Click += (_, _) => Close();
Content = new Border
{
Padding = new Avalonia.Thickness(22),
Child = new StackPanel
{
Spacing = 14,
Children =
{
new TextBlock
{
Text = "Applicazione scaduta",
FontSize = 18,
FontWeight = Avalonia.Media.FontWeight.SemiBold
},
new TextBlock
{
Text = message,
TextWrapping = Avalonia.Media.TextWrapping.Wrap
},
closeButton
}
}
};
}
}

View file

@ -0,0 +1,95 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using MaddoShared;
using Microsoft.Extensions.Logging;
namespace CatalogLite;
public readonly record struct ImageProcessedUpdate(string Status, int Total, int Processed);
public sealed class ImageProcessingRunResult
{
public required string FinalSpeedCounter { get; init; }
}
public sealed class ImageProcessingCoordinator
{
private readonly ImageCreationService _imageCreationService;
private readonly ILogger<ImageProcessingCoordinator> _logger;
public ImageProcessingCoordinator(ImageCreationService imageCreationService, ILogger<ImageProcessingCoordinator> logger)
{
_imageCreationService = imageCreationService;
_logger = logger;
}
public async Task<ImageProcessingRunResult> RunAsync(
ImageCreationService.Options options,
CancellationToken token,
Action<ImageProcessedUpdate> onImageProcessed,
Action<string> onSpeedUpdated)
{
var results = new ConcurrentBag<string>();
var recentDiffs = new Queue<int>();
const int recentWindowSize = 5;
var currentAmount = 0;
var previousAmount = 0;
var processedAtomic = 0;
var speedWatch = Stopwatch.StartNew();
using var speedTimer = new System.Threading.Timer(_ =>
{
try
{
previousAmount = currentAmount;
currentAmount = Volatile.Read(ref processedAtomic);
var diff = Math.Max(0, currentAmount - previousAmount);
lock (recentDiffs)
{
recentDiffs.Enqueue(diff);
if (recentDiffs.Count > recentWindowSize)
{
recentDiffs.Dequeue();
}
}
double recentAverage;
lock (recentDiffs)
{
recentAverage = recentDiffs.Count == 0 ? 0.0 : recentDiffs.Average();
}
var total = Volatile.Read(ref processedAtomic);
var overall = speedWatch.Elapsed.TotalSeconds > 0 ? total / speedWatch.Elapsed.TotalSeconds : 0.0;
var elapsed = speedWatch.Elapsed;
var elapsedText = $"{(int)elapsed.TotalHours}h {elapsed.Minutes}m {elapsed.Seconds}s";
onSpeedUpdated($"{recentAverage:0.00} f/s (media: {overall:0.00} f/s) - {elapsedText}{Environment.NewLine}media: {recentAverage * 60.0:0.00} f/m");
}
catch (Exception ex)
{
_logger.LogDebug(ex, "Errore durante l'aggiornamento della velocità");
}
}, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
EventHandler<Tuple<string, int>> onImageProcessedInternal = (_, args) =>
{
var processed = Interlocked.Increment(ref processedAtomic);
onImageProcessed(new ImageProcessedUpdate(args.Item1, args.Item2, processed));
};
await _imageCreationService.CreaCatalogoParallel(options, results, onImageProcessedInternal, token).ConfigureAwait(false);
speedWatch.Stop();
var finalProcessed = Volatile.Read(ref processedAtomic);
var finalAverage = speedWatch.Elapsed.TotalSeconds > 0 ? finalProcessed / speedWatch.Elapsed.TotalSeconds : 0.0;
var finalElapsed = speedWatch.Elapsed;
return new ImageProcessingRunResult
{
FinalSpeedCounter = $"{(int)finalElapsed.TotalHours}h {finalElapsed.Minutes}m {finalElapsed.Seconds}s{Environment.NewLine}media: {finalAverage:0.00} f/s{Environment.NewLine}media: {finalAverage * 60.0:0.00} f/m"
};
}
}

View file

@ -0,0 +1,349 @@
using MaddoShared;
using Microsoft.Extensions.Logging;
namespace CatalogLite;
public sealed class LiteCatalogViewModel : ViewModelBase
{
private readonly CatalogConfigurationLoader _configurationLoader;
private readonly PicSettings _picSettings;
private readonly ImageCreationService _imageCreationService;
private readonly ImageProcessingCoordinator _imageProcessingCoordinator;
private readonly ILogger<LiteCatalogViewModel> _logger;
private CatalogLiteConfiguration? _configuration;
private CancellationTokenSource? _processingTokenSource;
private string _configurationPath = string.Empty;
private string _sourcePath = string.Empty;
private string _destinationPath = string.Empty;
private string _processingStatus = "Carica una configurazione XML.";
private string _speedCounter = "-";
private int _processedImagesCount;
private int _totalImagesCount;
private int _progressBarValue;
private int _progressBarMaximum = 100;
private bool _isProcessing;
public LiteCatalogViewModel(
CatalogConfigurationLoader configurationLoader,
PicSettings picSettings,
ImageCreationService imageCreationService,
ImageProcessingCoordinator imageProcessingCoordinator,
ILogger<LiteCatalogViewModel> logger)
{
_configurationLoader = configurationLoader;
_picSettings = picSettings;
_imageCreationService = imageCreationService;
_imageProcessingCoordinator = imageProcessingCoordinator;
_logger = logger;
LoadConfigurationCommand = new AsyncCommand(RequestLoadConfigurationAsync, () => !IsProcessing);
SelectSourceFolderCommand = new AsyncCommand(RequestSourceFolderAsync, () => !IsProcessing);
SelectDestinationFolderCommand = new AsyncCommand(RequestDestinationFolderAsync, () => !IsProcessing);
StartProcessingCommand = new AsyncCommand(StartProcessingAsync, CanStartProcessing);
StopProcessingCommand = new AsyncCommand(StopProcessingAsync, () => IsProcessing);
}
public event EventHandler? LoadConfigurationRequested;
public event EventHandler? SelectSourceFolderRequested;
public event EventHandler? SelectDestinationFolderRequested;
public event EventHandler<LiteMessageEventArgs>? ShowMessageRequested;
public Action<Action>? UiInvoker { get; set; }
public AsyncCommand LoadConfigurationCommand { get; }
public AsyncCommand SelectSourceFolderCommand { get; }
public AsyncCommand SelectDestinationFolderCommand { get; }
public AsyncCommand StartProcessingCommand { get; }
public AsyncCommand StopProcessingCommand { get; }
public string ConfigurationPath
{
get => _configurationPath;
private set
{
_configurationPath = value;
NotifyPropertyChanged();
}
}
public string SourcePath
{
get => _sourcePath;
set
{
_sourcePath = NormalizeDirectoryPath(value);
NotifyPropertyChanged();
RaiseCommandStates();
}
}
public string DestinationPath
{
get => _destinationPath;
set
{
_destinationPath = NormalizeDirectoryPath(value);
NotifyPropertyChanged();
RaiseCommandStates();
}
}
public string ProcessingStatus
{
get => _processingStatus;
private set
{
_processingStatus = value;
NotifyPropertyChanged();
}
}
public string SpeedCounter
{
get => _speedCounter;
private set
{
_speedCounter = value;
NotifyPropertyChanged();
}
}
public int ProcessedImagesCount
{
get => _processedImagesCount;
private set
{
_processedImagesCount = value;
NotifyPropertyChanged();
}
}
public int TotalImagesCount
{
get => _totalImagesCount;
private set
{
_totalImagesCount = value;
NotifyPropertyChanged();
}
}
public int ProgressBarValue
{
get => _progressBarValue;
private set
{
_progressBarValue = value;
NotifyPropertyChanged();
}
}
public int ProgressBarMaximum
{
get => _progressBarMaximum;
private set
{
_progressBarMaximum = Math.Max(1, value);
NotifyPropertyChanged();
}
}
public bool IsProcessing
{
get => _isProcessing;
private set
{
_isProcessing = value;
NotifyPropertyChanged();
RaiseCommandStates();
}
}
public async Task LoadConfigurationFromFileAsync(string filePath)
{
try
{
var configuration = await Task.Run(() => _configurationLoader.Load(filePath, _picSettings)).ConfigureAwait(false);
RunOnUiThread(() =>
{
_configuration = configuration;
ConfigurationPath = configuration.FilePath;
SourcePath = configuration.SourcePath;
DestinationPath = configuration.DestinationPath;
ResetProgress("Configurazione caricata.");
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore durante il caricamento della configurazione");
ShowMessage("Configurazione", $"Impossibile caricare la configurazione: {ex.GetBaseException().Message}");
}
}
public static string NormalizeDirectoryPath(string? path)
{
if (string.IsNullOrWhiteSpace(path))
{
return string.Empty;
}
var trimmed = path.Trim().TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
return trimmed + Path.DirectorySeparatorChar;
}
private Task RequestLoadConfigurationAsync()
{
LoadConfigurationRequested?.Invoke(this, EventArgs.Empty);
return Task.CompletedTask;
}
private Task RequestSourceFolderAsync()
{
SelectSourceFolderRequested?.Invoke(this, EventArgs.Empty);
return Task.CompletedTask;
}
private Task RequestDestinationFolderAsync()
{
SelectDestinationFolderRequested?.Invoke(this, EventArgs.Empty);
return Task.CompletedTask;
}
private bool CanStartProcessing()
{
return !IsProcessing
&& _configuration is not null
&& !string.IsNullOrWhiteSpace(SourcePath)
&& !string.IsNullOrWhiteSpace(DestinationPath);
}
private async Task StartProcessingAsync()
{
if (_configuration is null)
{
ShowMessage("Configurazione", "Carica prima una configurazione XML.");
return;
}
if (!Directory.Exists(SourcePath))
{
ShowMessage("Sorgente", "La cartella sorgente non esiste.");
return;
}
try
{
Directory.CreateDirectory(DestinationPath);
}
catch (Exception ex)
{
ShowMessage("Destinazione", $"Impossibile usare la cartella destinazione: {ex.GetBaseException().Message}");
return;
}
_processingTokenSource?.Dispose();
_processingTokenSource = new CancellationTokenSource();
var token = _processingTokenSource.Token;
var options = CatalogConfigurationLoader.CloneOptions(_configuration.Options, SourcePath, DestinationPath);
_picSettings.DirectorySorgente = SourcePath;
_picSettings.DirectoryDestinazione = DestinationPath;
_picSettings.DestDir = new DirectoryInfo(DestinationPath);
IsProcessing = true;
ResetProgress("Analisi immagini...");
try
{
var total = await Task.Run(() => _imageCreationService.GetFilesToProcessPublic(options).Count, token).ConfigureAwait(false);
RunOnUiThread(() =>
{
TotalImagesCount = total;
ProgressBarMaximum = Math.Max(1, total);
ProcessingStatus = total == 0 ? "Nessuna immagine trovata." : "Elaborazione in corso...";
});
if (total == 0)
{
return;
}
var result = await _imageProcessingCoordinator.RunAsync(
options,
token,
update => RunOnUiThread(() =>
{
ProcessedImagesCount = update.Processed;
TotalImagesCount = update.Total;
ProgressBarMaximum = update.Total;
ProgressBarValue = update.Processed;
ProcessingStatus = update.Status;
}),
speed => RunOnUiThread(() => SpeedCounter = speed)).ConfigureAwait(false);
RunOnUiThread(() =>
{
SpeedCounter = result.FinalSpeedCounter;
ProcessingStatus = "Finito.";
});
}
catch (OperationCanceledException)
{
RunOnUiThread(() => ProcessingStatus = "Operazione annullata.");
}
catch (Exception ex)
{
_logger.LogError(ex, "Errore durante l'elaborazione");
RunOnUiThread(() => ProcessingStatus = $"Errore: {ex.GetBaseException().Message}");
}
finally
{
_processingTokenSource?.Dispose();
_processingTokenSource = null;
RunOnUiThread(() => IsProcessing = false);
}
}
private Task StopProcessingAsync()
{
_processingTokenSource?.Cancel();
ProcessingStatus = "Arresto in corso...";
return Task.CompletedTask;
}
private void ResetProgress(string status)
{
ProcessingStatus = status;
ProcessedImagesCount = 0;
TotalImagesCount = 0;
ProgressBarValue = 0;
ProgressBarMaximum = 100;
SpeedCounter = "-";
}
private void RunOnUiThread(Action action)
{
if (UiInvoker is null)
{
action();
return;
}
UiInvoker(action);
}
private void ShowMessage(string title, string message)
{
RunOnUiThread(() => ShowMessageRequested?.Invoke(this, new LiteMessageEventArgs(title, message)));
}
private void RaiseCommandStates()
{
LoadConfigurationCommand.RaiseCanExecuteChanged();
SelectSourceFolderCommand.RaiseCanExecuteChanged();
SelectDestinationFolderCommand.RaiseCanExecuteChanged();
StartProcessingCommand.RaiseCanExecuteChanged();
StopProcessingCommand.RaiseCanExecuteChanged();
}
}

View file

@ -0,0 +1,13 @@
namespace CatalogLite;
public sealed class LiteMessageEventArgs : EventArgs
{
public LiteMessageEventArgs(string title, string message)
{
Title = title;
Message = message;
}
public string Title { get; }
public string Message { get; }
}

View file

@ -0,0 +1,83 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:iconPacks="https://github.com/MahApps/IconPacks.Avalonia"
x:Class="CatalogLite.MainWindow"
x:CompileBindings="False"
Title="Catalog Lite"
Width="740"
Height="380"
MinWidth="640"
MinHeight="340">
<Grid Margin="16" RowDefinitions="Auto,Auto,Auto,*,Auto" RowSpacing="12">
<Grid ColumnDefinitions="150,*" ColumnSpacing="10">
<Button Command="{Binding LoadConfigurationCommand}" ToolTip.Tip="Carica configurazione XML">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="7">
<iconPacks:PackIconMaterial Kind="FolderUploadOutline" Width="16" Height="16" />
<TextBlock Text="Carica XML" />
</StackPanel>
</Button>
<TextBox Grid.Column="1"
Text="{Binding ConfigurationPath}"
IsReadOnly="True"
Watermark="Nessuna configurazione caricata" />
</Grid>
<Grid Grid.Row="1" ColumnDefinitions="150,*,116" ColumnSpacing="10">
<TextBlock Text="Sorgente" VerticalAlignment="Center" FontWeight="SemiBold" />
<TextBox Grid.Column="1" Text="{Binding SourcePath, Mode=TwoWay}" Watermark="Cartella sorgente" />
<Button Grid.Column="2" Command="{Binding SelectSourceFolderCommand}" ToolTip.Tip="Seleziona cartella sorgente">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="7">
<iconPacks:PackIconMaterial Kind="FolderOpenOutline" Width="16" Height="16" />
<TextBlock Text="Scegli" />
</StackPanel>
</Button>
</Grid>
<Grid Grid.Row="2" ColumnDefinitions="150,*,116" ColumnSpacing="10">
<TextBlock Text="Destinazione" VerticalAlignment="Center" FontWeight="SemiBold" />
<TextBox Grid.Column="1" Text="{Binding DestinationPath, Mode=TwoWay}" Watermark="Cartella destinazione" />
<Button Grid.Column="2" Command="{Binding SelectDestinationFolderCommand}" ToolTip.Tip="Seleziona cartella destinazione">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="7">
<iconPacks:PackIconMaterial Kind="FolderOpenOutline" Width="16" Height="16" />
<TextBlock Text="Scegli" />
</StackPanel>
</Button>
</Grid>
<Border Grid.Row="3"
Background="{DynamicResource PanelBackgroundBrush}"
BorderBrush="{DynamicResource BorderMutedBrush}"
BorderThickness="1"
Padding="14">
<Grid RowDefinitions="Auto,Auto,Auto,Auto" RowSpacing="8">
<TextBlock Text="{Binding ProcessingStatus}" TextWrapping="Wrap" />
<ProgressBar Grid.Row="1"
Minimum="0"
Maximum="{Binding ProgressBarMaximum}"
Value="{Binding ProgressBarValue}" />
<StackPanel Grid.Row="2" Orientation="Horizontal" Spacing="6">
<TextBlock Text="Elaborate" FontWeight="SemiBold" />
<TextBlock Text="{Binding ProcessedImagesCount}" />
<TextBlock Text="/" />
<TextBlock Text="{Binding TotalImagesCount}" />
</StackPanel>
<TextBlock Grid.Row="3" Text="{Binding SpeedCounter}" TextWrapping="Wrap" Opacity="0.78" />
</Grid>
</Border>
<StackPanel Grid.Row="4" Orientation="Horizontal" HorizontalAlignment="Right" Spacing="10">
<Button Command="{Binding StartProcessingCommand}" MinWidth="112" ToolTip.Tip="Avvia elaborazione">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="7">
<iconPacks:PackIconMaterial Kind="PlayCircleOutline" Width="16" Height="16" Foreground="{DynamicResource AccentBrush}" />
<TextBlock Text="Avvia" />
</StackPanel>
</Button>
<Button Command="{Binding StopProcessingCommand}" MinWidth="112" ToolTip.Tip="Ferma elaborazione">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="7">
<iconPacks:PackIconMaterial Kind="StopCircleOutline" Width="16" Height="16" Foreground="#B3261E" />
<TextBlock Text="Stop" />
</StackPanel>
</Button>
</StackPanel>
</Grid>
</Window>

View file

@ -0,0 +1,113 @@
using Avalonia.Controls;
using Avalonia.Platform.Storage;
using Avalonia.Threading;
using Microsoft.Extensions.DependencyInjection;
namespace CatalogLite;
public partial class MainWindow : Window
{
private readonly LiteCatalogViewModel _viewModel;
public MainWindow()
: this(Program.ServiceProvider.GetRequiredService<LiteCatalogViewModel>())
{
}
public MainWindow(LiteCatalogViewModel viewModel)
{
InitializeComponent();
_viewModel = viewModel;
DataContext = _viewModel;
_viewModel.UiInvoker = action => Dispatcher.UIThread.Invoke(action);
_viewModel.LoadConfigurationRequested += OnLoadConfigurationRequested;
_viewModel.SelectSourceFolderRequested += OnSelectSourceFolderRequested;
_viewModel.SelectDestinationFolderRequested += OnSelectDestinationFolderRequested;
_viewModel.ShowMessageRequested += OnShowMessageRequested;
}
private async void OnLoadConfigurationRequested(object? sender, EventArgs e)
{
var files = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = "Carica configurazione XML",
FileTypeFilter = [new FilePickerFileType("XML") { Patterns = ["*.xml"] }]
});
if (files.Count > 0)
{
await _viewModel.LoadConfigurationFromFileAsync(files[0].Path.LocalPath);
}
}
private async void OnSelectSourceFolderRequested(object? sender, EventArgs e)
{
var folders = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = "Seleziona cartella sorgente"
});
if (folders.Count > 0)
{
_viewModel.SourcePath = LiteCatalogViewModel.NormalizeDirectoryPath(folders[0].Path.LocalPath);
}
}
private async void OnSelectDestinationFolderRequested(object? sender, EventArgs e)
{
var folders = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = "Seleziona cartella destinazione"
});
if (folders.Count > 0)
{
_viewModel.DestinationPath = LiteCatalogViewModel.NormalizeDirectoryPath(folders[0].Path.LocalPath);
}
}
private async void OnShowMessageRequested(object? sender, LiteMessageEventArgs e)
{
await ShowMessageDialogAsync(e.Title, e.Message);
}
private async Task ShowMessageDialogAsync(string title, string message)
{
var closeButton = new Button
{
Content = "OK",
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Right,
MinWidth = 92
};
var dialog = new Window
{
Title = title,
Width = 420,
Height = 180,
CanResize = false,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Content = new Border
{
Padding = new Avalonia.Thickness(20),
Child = new StackPanel
{
Spacing = 14,
Children =
{
new TextBlock
{
Text = message,
TextWrapping = Avalonia.Media.TextWrapping.Wrap
},
closeButton
}
}
}
};
closeButton.Click += (_, _) => dialog.Close();
await dialog.ShowDialog(this);
}
}

45
CatalogLite/Program.cs Normal file
View file

@ -0,0 +1,45 @@
using Avalonia;
using MaddoShared;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace CatalogLite;
internal static class Program
{
public static IServiceProvider ServiceProvider { get; private set; } = default!;
[STAThread]
public static int Main(string[] args)
{
var services = new ServiceCollection();
ConfigureServices(services);
ServiceProvider = services.BuildServiceProvider();
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args ?? []);
return 0;
}
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace();
private static void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<PicSettings>();
services.AddSingleton<CatalogConfigurationLoader>();
services.AddTransient<ImageCreatorImageSharp>();
services.AddTransient<IImageCreator>(sp => sp.GetRequiredService<ImageCreatorImageSharp>());
services.AddTransient<ImageCreationService>();
services.AddTransient<ImageProcessingCoordinator>();
services.AddTransient<LiteCatalogViewModel>();
services.AddTransient<MainWindow>();
services.AddLogging(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Information);
});
}
}

View file

@ -0,0 +1,14 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace CatalogLite;
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

View file

@ -1,44 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<OutputType>Library</OutputType>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>embedded</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>embedded</DebugType>
</PropertyGroup>
<ItemGroup>
<Compile Update="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<Compile Update="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="My Project\Settings.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Ben.Demystifier" Version="0.4.1" />
<PackageReference Include="System.Collections.Immutable" Version="8.0.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="System.Reflection.Metadata" Version="8.0.1" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>
</Project>

View file

@ -1,3 +0,0 @@
Public Class Class1
End Class

File diff suppressed because it is too large Load diff

View file

@ -1,844 +0,0 @@
Imports System.Drawing
Imports System.IO
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging
Imports System.Windows.Forms
'Imports System.Threading
Public Class ImageCreator
#Region "dichiarazioni"
Private FotoRuotaADestra As Boolean = False
Private FotoRuotaASinistra As Boolean = False
Private TempMinText As String = ""
'Private crFont1 As Font
Private _NomeFileChild As String
Private _SourceDir As DirectoryInfo
Private _DestDirStart As DirectoryInfo
Private _DestDir As DirectoryInfo
Private _workFile As FileInfo
Private testoFirma As String
Private testoFirmaV As String
Private alphaScelta As Integer
Private DimensioneStandard As Integer
Private DimensioneStandardMiniatura As Integer
Private dataFoto As DateTime
Private dataPartenzaI As DateTime
Private testoOrario As String
Private testoFirmaPiccola As String
Private thumbSizeSmall As Size
Private thumbSizeBig As Size
Private nomeFileSmall As String
Private nomeFileBig As String
Private nomeFileBig2 As String
Private yPosFromBottom As Single
Private yPosFromBottom1 As Single
Private yPosFromBottom2 As Single
Private yPosFromBottom3 As Single
Private yPosFromBottom4 As Single
#End Region
Public Sub New()
End Sub
Public Sub New(ByVal nomeFileChild As String, ByVal sourceDir As DirectoryInfo, ByVal destDir As DirectoryInfo, ByVal destDirStart As DirectoryInfo)
Me.NomeFileChild = nomeFileChild
Me.SourceDir = sourceDir
Me.DestDir = destDir
Me.DestDirStart = destDirStart
Me.WorkFile = New FileInfo(nomeFileChild)
End Sub
Public Sub New(ByVal nomeFileChild As String, ByVal sourceDir As DirectoryInfo, ByVal destDir As DirectoryInfo)
Me.NomeFileChild = nomeFileChild
Me.DestDir = destDir
End Sub
Public Sub New(ByVal file As FileInfo, ByVal destination As DirectoryInfo)
Me.WorkFile = file
Me.DestDir = destination
End Sub
Public Sub CreaImmagineThread(ByVal Info As String)
Try
preparaVariabili()
'Dim g As System.Drawing.Image = System.Drawing.Image.FromFile(Path.Combine(SourceDir.FullName, NomeFileChild))
Using g As Image = Image.FromFile(WorkFile.FullName)
'Dim g As System.Drawing.Image = System.Drawing.Image.FromFile(WorkFile.FullName)
' Imposta testo extra
impostaTestoExtra(g)
' Ruota l'immagine in base ai dati EXIF
Rotation(g)
' Forza jpeg se è selezionata l'opzione
Dim thisFormat As System.Drawing.Imaging.ImageFormat = g.RawFormat
If PicSettings.UsaForzaJpg = True Then thisFormat = System.Drawing.Imaging.ImageFormat.Jpeg
prepareThumbnailSize(g)
Dim imgOutputBig As New Bitmap(g, thumbSizeBig.Width, thumbSizeBig.Height)
imgOutputBig.SetResolution(g.HorizontalResolution, g.VerticalResolution)
' Crea le miniature
creaMiniature(g, imgOutputBig, thisFormat)
aggiungiTesto(g, imgOutputBig)
aggiungiLogo(imgOutputBig)
salvaFoto(imgOutputBig, thumbSizeBig, nomeFileBig, nomeFileSmall, thumbSizeSmall, thisFormat)
End Using
'g.Dispose()
GC.Collect()
'PicSettings.mainForm.stepProgressBar()
Catch ex As Exception
Dim e = ex.Demystify()
Console.WriteLine(e)
Console.WriteLine(e.Message)
Console.WriteLine(e.StackTrace)
'MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub Rotation(ByRef g As System.Drawing.Image)
FotoRuotaADestra = False
FotoRuotaASinistra = False
If PicSettings.UsaRotazioneAutomatica = True Then
If g.PropertyIdList.Length > 0 Then ' ci sono dati exif
Dim DatiExif As New ExifReader(CType(g, Bitmap))
Select Case DatiExif.Orientation
Case ExifReader.Orientations.BottomLeft
Case ExifReader.Orientations.BottomRight
Case ExifReader.Orientations.LeftTop
Case ExifReader.Orientations.LftBottom
FotoRuotaASinistra = True
Case ExifReader.Orientations.RightBottom
Case ExifReader.Orientations.RightTop
Case ExifReader.Orientations.TopLeft
Case ExifReader.Orientations.TopRight
End Select
End If
End If
If FotoRuotaASinistra = True Then
g.RotateFlip(RotateFlipType.Rotate270FlipNone)
End If
If FotoRuotaADestra = True Then
g.RotateFlip(RotateFlipType.Rotate90FlipNone)
End If
End Sub
''' <summary>
''' Aggiunge Orario, tempo gara e altri
''' </summary>
''' <param name="g">Image</param>
''' <remarks></remarks>
Private Sub impostaTestoExtra(g As Image)
If PicSettings.UsaOrarioTestoApplicare Or
PicSettings.UsaTempoGaraTestoApplicare Or
PicSettings.UsaOrarioMiniatura Or
PicSettings.TestoMin Or
PicSettings.AggTempoGaraMin Or
PicSettings.AggNumTempMin Then
If g.PropertyIdList.Length > 0 Then ' ci sono dati exif
Dim DatiExif As New ExifReader(CType(g, Bitmap))
dataFoto = DatiExif.DateTimeOriginal
testoFirma = PicSettings.TestoFirmaStart
testoFirmaV = PicSettings.TestoFirmaStartV
If dataFoto.Year <> 1 Then
testoFirmaPiccola = dataFoto.ToShortTimeString
If PicSettings.UsaOrarioTestoApplicare = True Then
testoFirma &= " " & dataFoto.ToShortDateString & " " & dataFoto.ToLongTimeString
testoFirmaV &= " " & dataFoto.ToShortDateString & " " & dataFoto.ToLongTimeString
End If
If PicSettings.UsaTempoGaraTestoApplicare = True Then
Dim Orario As TimeSpan = New TimeSpan(DateDiff(DateInterval.Second, dataPartenzaI, dataFoto) * 10000000)
testoFirma &= " " & testoOrario & Orario.Hours.ToString("00") & ":" & Orario.Minutes.ToString("00") & ":" & Orario.Seconds.ToString("00")
testoFirmaV &= " " & testoOrario & Orario.Hours.ToString("00") & ":" & Orario.Minutes.ToString("00") & ":" & Orario.Seconds.ToString("00")
End If
End If
End If
Else
testoFirma = PicSettings.TestoFirmaStart
testoFirmaV = PicSettings.TestoFirmaStartV
End If
End Sub
''' <summary>
''' Prepara diverse variabili azzerandole, elaborandole e prendendole dalle impostazioni
''' </summary>
''' <remarks></remarks>
Private Sub preparaVariabili()
alphaScelta = CType((255 * (100 - PicSettings.Trasparenza) / 100), Integer)
testoFirma = ""
testoFirmaV = ""
dataPartenzaI = PicSettings.DataPartenza
testoOrario = PicSettings.TestoOrario
If testoOrario.Length > 0 Then testoOrario &= " "
testoFirmaPiccola = ""
thumbSizeSmall = New Size
thumbSizeBig = New Size
nomeFileSmall = ""
nomeFileBig2 = ""
nomeFileBig = ""
DimensioneStandard = PicSettings.DimStandard
DimensioneStandardMiniatura = PicSettings.DimStandardMiniatura
'nomeFileSmall = Suffisso & NomeFileChild
'nomeFileBig = NomeFileChild
nomeFileSmall = Suffisso & WorkFile.Name
nomeFileBig = WorkFile.Name
End Sub
Private Sub prepareThumbnailSize(g As Image)
If g.Width > g.Height Then
thumbSizeSmall = NewthumbSize(g.Width, g.Height, LarghezzaSmall, "Larghezza")
Dim SizeOrig As New Size(g.Width, g.Height)
thumbSizeBig = SizeOrig
Else
thumbSizeSmall = NewthumbSize(g.Width, g.Height, AltezzaSmall, "Altezza")
Dim SizeOrig As New Size(g.Width, g.Height)
thumbSizeBig = SizeOrig
End If
End Sub
Private Sub creaMiniature(g As Image, imgOutputBig As Bitmap, thisFormat As ImageFormat)
If PicSettings.TestoMin Then
testoFirmaPiccola = nomeFileBig
ElseIf PicSettings.AggNumTempMin Then
testoFirmaPiccola = nomeFileBig + " "
End If
'Dim yPosFromBottom4 As Single
Dim crFont1 As Font = Nothing
Dim crFont2 As Font = Nothing
Dim crSize1 As SizeF = New SizeF
Dim crSize2 As SizeF = New SizeF
If PicSettings.CreaMiniature = True Then
If PicSettings.AggiungiScritteMiniature = False Then
If PicSettings.DirectorySorgente.ToUpper = PicSettings.DirectoryDestinazione.ToUpper Then
nomeFileSmall = nomeFileSmall.Substring(0, nomeFileSmall.Length - 4) & Codice & nomeFileSmall.Substring(nomeFileSmall.Length - 4)
End If
If PicSettings.UsaOrarioMiniatura Or
PicSettings.TestoMin Or
PicSettings.AggTempoGaraMin Or
PicSettings.AggNumTempMin Then
If testoFirmaPiccola.Length > 0 Then
Dim imgOutputSmall As Bitmap
imgOutputSmall = CType(imgOutputBig.Clone, Bitmap)
Dim grPhoto1 As Graphics
grPhoto1 = Graphics.FromImage(imgOutputSmall)
grPhoto1.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
Dim LarghezzaStandard1 As Integer
'quick fix
DimensioneStandardMiniatura = 50
If PicSettings.Grassetto = True Then
crFont1 = New Font(PicSettings.IlFont, DimensioneStandardMiniatura, FontStyle.Bold)
crFont2 = New Font(PicSettings.IlFont, DimensioneStandard, FontStyle.Bold)
Else
crFont1 = New Font(PicSettings.IlFont, DimensioneStandardMiniatura)
crFont2 = New Font(PicSettings.IlFont, DimensioneStandard)
End If
crSize1 = grPhoto1.MeasureString(testoFirmaPiccola, crFont1)
crSize2 = grPhoto1.MeasureString(testoFirma, crFont1)
LarghezzaStandard1 = CType(crSize1.Width, Integer)
If crSize1.Width > CType(g.Width, Single) Then
Dim Conta As Integer = DimensioneStandardMiniatura
Do
If Conta > 20 Then
Conta -= 5
Else
Conta -= 1
End If
If PicSettings.Grassetto = True Then
crFont1 = New Font(PicSettings.IlFont, Conta, FontStyle.Bold)
Else
crFont1 = New Font(PicSettings.IlFont, Conta)
End If
crSize1 = grPhoto1.MeasureString(testoFirmaPiccola, crFont1)
If crSize1.Width < CType(g.Width, Single) Then
LarghezzaStandard1 = CType(crSize1.Width, Integer)
Exit Do
End If
If Conta <= 5 Then Exit Do
Loop
DimensioneStandardMiniatura = Conta
End If
Select Case PicSettings.Posizione.ToUpper
Case "ALTO"
yPosFromBottom1 = (PicSettings.Margine)
yPosFromBottom4 = (PicSettings.MargVert)
Case "BASSO"
yPosFromBottom1 = CType((g.Height - crSize1.Height - (g.Height * PicSettings.Margine / 100)), Single)
yPosFromBottom4 = CType((g.Height - crSize1.Height - (g.Height * PicSettings.MargVert / 100)), Single)
End Select
Dim xCenterOfImg1 As Single
Dim StrFormat1 As StringFormat = New StringFormat
Select Case PicSettings.Allineamento.ToUpper
Case "SINISTRA"
xCenterOfImg1 = CType((PicSettings.Margine + (LarghezzaStandard1 / 2)), Single)
If (LarghezzaStandard1 / 2) > (g.Width / 2) - PicSettings.Margine Then
xCenterOfImg1 = CType((g.Width / 2), Single)
End If
Case "CENTRO"
xCenterOfImg1 = CType((g.Width / 2), Single)
Case "DESTRA"
xCenterOfImg1 = CType((g.Width - PicSettings.Margine - (LarghezzaStandard1 / 2)), Single)
If (LarghezzaStandard1 / 2) > (g.Width / 2) - PicSettings.Margine Then
xCenterOfImg1 = CType((g.Width / 2), Single)
End If
End Select
StrFormat1.Alignment = StringAlignment.Center
Dim semiTransBrush21 As SolidBrush = New SolidBrush(Color.FromArgb(alphaScelta, 0, 0, 0))
Dim semiTransBrush1 As SolidBrush = New SolidBrush(Color.FromArgb(alphaScelta, PicSettings.fontColoreRGB))
'quick fix
DimensioneStandardMiniatura = PicSettings.DimMin
If PicSettings.Grassetto = True Then
crFont1 = New Font(PicSettings.IlFont, DimensioneStandardMiniatura, FontStyle.Bold)
Else
crFont1 = New Font(PicSettings.IlFont, DimensioneStandardMiniatura)
End If
'asdgadfhdfhjgfsjgfjygfdhsdafa
If PicSettings.TestoMin Then
grPhoto1.DrawString(nomeFileBig, crFont1, semiTransBrush21, New PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1), StrFormat1)
grPhoto1.DrawString(nomeFileBig, crFont1, semiTransBrush1, New PointF(xCenterOfImg1, yPosFromBottom1), StrFormat1)
ElseIf PicSettings.AggTempoGaraMin And PicSettings.UsaTempoGaraTestoApplicare Then
Dim Orario As TimeSpan = New TimeSpan(DateDiff(DateInterval.Second, dataPartenzaI, dataFoto) * 10000000)
Dim tempstr As String = ""
tempstr &= ControlChars.CrLf & testoOrario & Orario.Hours.ToString("00") & ":" & Orario.Minutes.ToString("00") & ":" & Orario.Seconds.ToString("00")
grPhoto1.DrawString(tempstr, crFont1, semiTransBrush21, New PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1), StrFormat1)
grPhoto1.DrawString(tempstr, crFont1, semiTransBrush1, New PointF(xCenterOfImg1, yPosFromBottom1), StrFormat1)
ElseIf PicSettings.AggNumTempMin Then
Dim Orario As TimeSpan = New TimeSpan(DateDiff(DateInterval.Second, dataPartenzaI, dataFoto) * 10000000)
Dim tempstr As String = ""
tempstr &= nomeFileBig
tempstr &= ControlChars.CrLf & testoOrario & Orario.Hours.ToString("00") & ":" & Orario.Minutes.ToString("00") & ":" & Orario.Seconds.ToString("00")
grPhoto1.DrawString(tempstr, crFont1, semiTransBrush21, New PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1), StrFormat1)
grPhoto1.DrawString(tempstr, crFont1, semiTransBrush1, New PointF(xCenterOfImg1, yPosFromBottom1), StrFormat1)
Else
grPhoto1.DrawString(testoFirmaPiccola, crFont1, semiTransBrush21, New PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1), StrFormat1)
grPhoto1.DrawString(testoFirmaPiccola, crFont1, semiTransBrush1, New PointF(xCenterOfImg1, yPosFromBottom1), StrFormat1)
End If
' Salva la miniatura
imgOutputSmall.Save(Path.Combine(DestDir.FullName, "Temp_" & nomeFileSmall), thisFormat)
Dim g2 As System.Drawing.Image = System.Drawing.Image.FromFile(Path.Combine(DestDir.FullName, "Temp_" & nomeFileSmall))
Dim imgOutputSmall2 As New Bitmap(g2, thumbSizeSmall.Width, thumbSizeSmall.Height)
imgOutputSmall2.Save(Path.Combine(DestDir.FullName, nomeFileSmall), thisFormat)
imgOutputSmall2.Dispose()
imgOutputSmall.Dispose()
g2.Dispose()
Kill(Path.Combine(DestDir.FullName, "Temp_" & nomeFileSmall))
Else
Dim imgOutputSmall As New Bitmap(g, thumbSizeSmall.Width, thumbSizeSmall.Height)
imgOutputSmall.Save(Path.Combine(DestDir.FullName, nomeFileSmall), thisFormat)
imgOutputSmall.Dispose()
End If
Else
Dim imgOutputSmall As New Bitmap(g, thumbSizeSmall.Width, thumbSizeSmall.Height)
imgOutputSmall.Save(Path.Combine(DestDir.FullName, nomeFileSmall), thisFormat)
imgOutputSmall.Dispose()
End If
End If
End If
End Sub
Private Sub aggiungiTesto(g As Image, imgOutputBig As Bitmap)
Dim grPhoto As Graphics
grPhoto = Graphics.FromImage(imgOutputBig)
grPhoto.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
Dim crFont As Font = Nothing
Dim crSize As SizeF = New SizeF
Dim LarghezzaStandard As Integer
If PicSettings.Grassetto = True Then
crFont = New Font(PicSettings.IlFont, DimensioneStandard, FontStyle.Bold)
Else
crFont = New Font(PicSettings.IlFont, DimensioneStandard)
End If
crSize = grPhoto.MeasureString(testoFirma, crFont)
LarghezzaStandard = CType(crSize.Width, Integer)
If crSize.Width > CType(g.Width, Single) Then
Dim Conta As Integer = DimensioneStandard
Do
If Conta > 20 Then
Conta -= 5
Else
Conta -= 1
End If
If PicSettings.Grassetto = True Then
crFont = New Font(PicSettings.IlFont, Conta, FontStyle.Bold)
Else
crFont = New Font(PicSettings.IlFont, Conta)
End If
crSize = grPhoto.MeasureString(testoFirma, crFont)
If crSize.Width < CType(g.Width, Single) Then
LarghezzaStandard = CType(crSize.Width, Integer)
Exit Do
End If
If Conta <= 5 Then Exit Do
Loop
DimensioneStandard = Conta
End If
Select Case PicSettings.Posizione.ToUpper
Case "ALTO"
yPosFromBottom = (PicSettings.Margine)
yPosFromBottom3 = (PicSettings.MargVert)
Case "BASSO"
yPosFromBottom = CType((g.Height - crSize.Height - (g.Height * PicSettings.Margine / 100)), Single)
yPosFromBottom3 = CType((g.Height - crSize.Height - (g.Height * PicSettings.MargVert / 100)), Single)
End Select
Dim xCenterOfImg As Single
Dim xCenterOfImg3 As Single
Dim StrFormat As StringFormat = New StringFormat
Select Case PicSettings.Allineamento.ToUpper
Case "SINISTRA"
xCenterOfImg = CType((PicSettings.Margine + (LarghezzaStandard / 2)), Single)
xCenterOfImg3 = CType((PicSettings.MargVert + (LarghezzaStandard / 2)), Single)
If (LarghezzaStandard / 2) > (g.Width / 2) - PicSettings.Margine Then
xCenterOfImg = CType((g.Width / 2), Single)
End If
If (LarghezzaStandard / 2) > (g.Width / 2) - PicSettings.MargVert Then
xCenterOfImg3 = CType((g.Width / 2), Single)
End If
Case "CENTRO"
xCenterOfImg = CType((g.Width / 2), Single)
Case "DESTRA"
xCenterOfImg = CType((g.Width - PicSettings.Margine - (LarghezzaStandard / 2)), Single)
xCenterOfImg3 = CType((g.Width - PicSettings.MargVert - (LarghezzaStandard / 2)), Single)
If (LarghezzaStandard / 2) > (g.Width / 2) - PicSettings.Margine Then
xCenterOfImg = CType((g.Width / 2), Single)
End If
If (LarghezzaStandard / 2) > (g.Width / 2) - PicSettings.MargVert Then
xCenterOfImg3 = CType((g.Width / 2), Single)
End If
End Select
StrFormat.Alignment = StringAlignment.Center
Dim semiTransBrush2 As SolidBrush = New SolidBrush(Color.FromArgb(alphaScelta, 0, 0, 0))
'Dim semiTransBrush As SolidBrush = New SolidBrush(Color.FromArgb(AlphaScelta, _FontColoreR, _FontColoreG, _FontColoreB))
Dim semiTransBrush As SolidBrush = New SolidBrush(Color.FromArgb(alphaScelta, PicSettings.fontColoreRGB))
If FotoRuotaADestra Or FotoRuotaASinistra Then
If PicSettings.Grassetto = True Then
crFont = New Font(PicSettings.IlFont, DimVert, FontStyle.Bold)
Else
crFont = New Font(PicSettings.IlFont, DimVert)
End If
Else
If PicSettings.Grassetto = True Then
crFont = New Font(PicSettings.IlFont, DimensioneStandard, FontStyle.Bold)
Else
crFont = New Font(PicSettings.IlFont, DimensioneStandard)
End If
End If
'qui scrive il testo (nomefilebig)
If PicSettings.TestoNome Then
If NomeData And g.PropertyIdList.Length > 0 Then
Dim DatiExif As New ExifReader(CType(g, Bitmap))
dataFoto = DatiExif.DateTimeOriginal
grPhoto.DrawString((nomeFileBig & " " & dataFoto.ToShortDateString), crFont, semiTransBrush2, New PointF(xCenterOfImg + 1, yPosFromBottom + 1), StrFormat)
grPhoto.DrawString((nomeFileBig & " " & dataFoto.ToShortDateString), crFont, semiTransBrush, New PointF(xCenterOfImg, yPosFromBottom), StrFormat)
Else
grPhoto.DrawString(nomeFileBig, crFont, semiTransBrush2, New PointF(xCenterOfImg + 1, yPosFromBottom + 1), StrFormat)
grPhoto.DrawString(nomeFileBig, crFont, semiTransBrush, New PointF(xCenterOfImg, yPosFromBottom), StrFormat)
End If
End If
If PicSettings.TestoNome = False Then
If FotoRuotaADestra Or FotoRuotaASinistra Then
If PicSettings.TestoMin = False Then
grPhoto.DrawString(testoFirmaV, crFont, semiTransBrush2, New PointF(xCenterOfImg + 1, yPosFromBottom3 + 1), StrFormat)
grPhoto.DrawString(testoFirmaV, crFont, semiTransBrush, New PointF(xCenterOfImg, yPosFromBottom3), StrFormat)
End If
If PicSettings.TestoMin = True Then
grPhoto.DrawString(testoFirmaV, crFont, semiTransBrush2, New PointF(xCenterOfImg + 1, yPosFromBottom4 + 1), StrFormat)
grPhoto.DrawString(testoFirmaV, crFont, semiTransBrush, New PointF(xCenterOfImg, yPosFromBottom4), StrFormat)
End If
Else
grPhoto.DrawString(testoFirma, crFont, semiTransBrush2, New PointF(xCenterOfImg + 1, yPosFromBottom + 1), StrFormat)
grPhoto.DrawString(testoFirma, crFont, semiTransBrush, New PointF(xCenterOfImg, yPosFromBottom), StrFormat)
End If
End If
If PicSettings.DirectorySorgente.ToUpper = PicSettings.DirectoryDestinazione.ToUpper Then
nomeFileBig2 = nomeFileBig
nomeFileBig = nomeFileBig.Substring(0, nomeFileBig.Length - 4) & Codice & nomeFileBig.Substring(nomeFileBig.Length - 4)
End If
grPhoto.Dispose()
End Sub
Private Sub aggiungiLogo(imgOutputBig As Bitmap)
'imgOutputBig
If PicSettings.LogoAggiungi = True And File.Exists(PicSettings.LogoNomeFile) Then
Dim ImmagineLogo As Image = Image.FromFile(PicSettings.LogoNomeFile)
Dim LogoColoreTrasparente As Color = Color.White
'Dim bmWatermark As Bitmap
'* Create a Bitmap based on the previously modified photograph Bitmap
'bmWatermark = New Bitmap(imgOutputBig)
'bmWatermark.SetResolution(imgOutputBig.HorizontalResolution, imgOutputBig.VerticalResolution)
'* Load this Bitmap into a new Graphic Object
Dim grWatermark As Graphics = Graphics.FromImage(imgOutputBig)
'* To achieve a translucent watermark we will apply (2) color manipulations
Dim imageAttributes As Imaging.ImageAttributes = New Imaging.ImageAttributes
'* The first step replace the background color with one that is transparent (Alpha=0, R=0, G=0, B=0)
Dim colorMap As Imaging.ColorMap = New Imaging.ColorMap
'* background this will be the color we search for and replace with transparency
colorMap.OldColor = LogoColoreTrasparente
colorMap.NewColor = Color.FromArgb(0, 0, 0, 0)
Dim remapTable As Imaging.ColorMap() = {colorMap}
imageAttributes.SetRemapTable(remapTable, Imaging.ColorAdjustType.Bitmap)
'* The second color manipulation is used to change the opacity by setting the 3rd row and 3rd column to 0.3f
Dim colorMatrixElements As Single()() = {New Single() {1.0F, 0.0F, 0.0F, 0.0F, 0.0F}, New Single() {0.0F, 1.0F, 0.0F, 0.0F, 0.0F}, New Single() {0.0F, 0.0F, 1.0F, 0.0F, 0.0F}, New Single() {0.0F, 0.0F, 0.0F, CType(PicSettings.LogoTrasparenza, Single) / 100, 0.0F}, New Single() {0.0F, 0.0F, 0.0F, 0.0F, 1.0F}}
Dim wmColorMatrix As Imaging.ColorMatrix = New Imaging.ColorMatrix(colorMatrixElements)
imageAttributes.SetColorMatrix(wmColorMatrix, Imaging.ColorMatrixFlag.Default, Imaging.ColorAdjustType.Bitmap)
Dim FotoLogoH As Integer = PicSettings.LogoAltezza
Dim FotoLogoW As Integer = PicSettings.LogoLarghezza
Dim FattoreAlt As Double = ImmagineLogo.Height / FotoLogoH
Dim FattoreLarg As Double = ImmagineLogo.Width / FotoLogoW
Dim NuovaSize As Size
If FattoreLarg > FattoreAlt Then
NuovaSize = NewthumbSize(ImmagineLogo.Width, ImmagineLogo.Height, FotoLogoW, "Larghezza")
Else
NuovaSize = NewthumbSize(ImmagineLogo.Width, ImmagineLogo.Height, FotoLogoH, "Altezza")
End If
Dim MargineUsato As Integer
Dim MargineL As Integer
Dim InPercentualeL As Boolean
If PicSettings.LogoMargine.EndsWith("%") = True Then
InPercentualeL = True
Else
InPercentualeL = False
End If
MargineL = CType(Val(PicSettings.LogoMargine), Integer)
If InPercentualeL = True Then
MargineUsato = CType(imgOutputBig.Height * MargineL / 100, Integer)
Else
MargineUsato = MargineL
End If
Dim xPosOfWm As Integer
Dim yPosOfWm As Integer
Select Case PicSettings.LogoPosizioneH.ToUpper
Case "SINISTRA", "NESSUNA"
xPosOfWm = MargineUsato
Case "CENTRO"
xPosOfWm = CType((imgOutputBig.Width - NuovaSize.Width) / 2, Integer)
Case "DESTRA"
xPosOfWm = ((imgOutputBig.Width - NuovaSize.Width) - MargineUsato)
End Select
Select Case PicSettings.LogoPosizioneV.ToUpper
Case "ALTO", "NESSUNA"
yPosOfWm = MargineUsato
Case "CENTRO"
yPosOfWm = CType((imgOutputBig.Height - NuovaSize.Height) / 2, Integer)
Case "BASSO"
yPosOfWm = ((imgOutputBig.Height - NuovaSize.Height) - MargineUsato)
End Select
grWatermark.DrawImage(ImmagineLogo, New Rectangle(xPosOfWm, yPosOfWm, NuovaSize.Width, NuovaSize.Height), 0, 0, ImmagineLogo.Width, ImmagineLogo.Height, GraphicsUnit.Pixel, imageAttributes)
grWatermark.Dispose()
End If
End Sub
Private Sub salvaFoto(imgOutputBig As Bitmap, thumbSizeBig As Size, NomeFileBig As String, NomeFileSmall As String, thumbSizeSmall As Size, thisFormat As ImageFormat)
If PicSettings.FotoGrandeDimOrigina = False Then
'attenzione non controlla se è png
'imgOutputBig.Save(Path.Combine(_DestDir.FullName, "Temp_" & NomeFileBig), thisFormat)
If thisFormat.Equals(ImageFormat.Jpeg) Then
salvaImmagineCustomQuality(imgOutputBig, Path.Combine(DestDir.FullName, "Temp_" & NomeFileBig), jpegQuality)
Else
imgOutputBig.Save(Path.Combine(_DestDir.FullName, "Temp_" & NomeFileBig), thisFormat)
End If
Dim g2 As System.Drawing.Image = System.Drawing.Image.FromFile(Path.Combine(DestDir.FullName, "Temp_" & NomeFileBig))
If g2.Width > g2.Height Then
thumbSizeBig = NewthumbSize(g2.Width, g2.Height, PicSettings.LarghezzaBig, "Larghezza")
Else
thumbSizeBig = NewthumbSize(g2.Width, g2.Height, PicSettings.AltezzaBig, "Altezza")
End If
Dim imgOutputBig2 As New Bitmap(g2, thumbSizeBig.Width, thumbSizeBig.Height)
'
If thisFormat.Equals(ImageFormat.Jpeg) Then
salvaImmagineCustomQuality(imgOutputBig2, Path.Combine(DestDir.FullName, NomeFileBig), jpegQuality)
Else
imgOutputBig2.Save(Path.Combine(_DestDir.FullName, NomeFileBig), thisFormat)
End If
imgOutputBig2.Dispose()
imgOutputBig.Dispose()
g2.Dispose()
Else
'
If thisFormat.Equals(ImageFormat.Jpeg) Then
salvaImmagineCustomQuality(imgOutputBig, Path.Combine(DestDir.FullName, NomeFileBig), jpegQuality)
Else
imgOutputBig.Save(Path.Combine(_DestDir.FullName, NomeFileBig), thisFormat)
End If
imgOutputBig.Dispose()
End If
If PicSettings.CreaMiniature Then
If PicSettings.AggiungiScritteMiniature = True Then
Dim g1 As System.Drawing.Image
If PicSettings.FotoGrandeDimOrigina = False Then
g1 = System.Drawing.Image.FromFile(Path.Combine(DestDir.FullName, "Temp_" & NomeFileBig))
Else
g1 = System.Drawing.Image.FromFile(Path.Combine(DestDir.FullName, NomeFileBig))
End If
Dim imgOutputSmall As New Bitmap(g1, thumbSizeSmall.Width, thumbSizeSmall.Height)
If PicSettings.DirectorySorgente.ToUpper = PicSettings.DirectoryDestinazione.ToUpper Then
NomeFileSmall = NomeFileSmall.Substring(0, NomeFileSmall.Length - 4) & Codice & NomeFileSmall.Substring(NomeFileSmall.Length - 4)
End If
'
If thisFormat.Equals(ImageFormat.Jpeg) Then
salvaImmagineCustomQuality(imgOutputSmall, Path.Combine(DestDir.FullName, NomeFileSmall), jpegQualityMin)
Else
imgOutputSmall.Save(Path.Combine(_DestDir.FullName, NomeFileSmall), thisFormat)
End If
imgOutputSmall.Dispose()
g1.Dispose()
End If
End If
If File.Exists(Path.Combine(DestDir.FullName, "Temp_" & NomeFileBig)) = True Then
Kill(Path.Combine(DestDir.FullName, "Temp_" & NomeFileBig))
End If
End Sub
Private Sub salvaImmagineCustomQuality(imageToSave As Bitmap, nomeFileFinale As String, quality As Long)
Dim JgpEncoder As ImageCodecInfo = GetEncoder(ImageFormat.Jpeg)
Dim MyEncoder As Encoder = Encoder.Quality
Dim MyEncoderParameters As New EncoderParameters(1)
Dim MyEncoderParameter As New EncoderParameter(MyEncoder, jpegQuality)
MyEncoderParameters.Param(0) = MyEncoderParameter
imageToSave.Save(nomeFileFinale, JgpEncoder, MyEncoderParameters)
imageToSave.Dispose()
End Sub
Private Function GetEncoder(ByVal format As ImageFormat) As ImageCodecInfo
Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageDecoders()
Dim codec As ImageCodecInfo
For Each codec In codecs
If codec.FormatID = format.Guid Then
Return codec
End If
Next codec
Return Nothing
End Function
''' <summary>
''' Calculate the Size of the New image
''' </summary>
''' <param name="currentwidth">Larghezza</param>
''' <param name="currentheight">Altezza</param>
''' <param name="MaxPixel"></param>
''' <param name="TipoSize"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Function NewthumbSize(ByVal currentwidth As Integer, ByVal currentheight As Integer, ByVal MaxPixel As Integer, ByVal TipoSize As String) As Size
' e
'*** Larghezza, Altezza, Auto
Dim tempMultiplier As Double
If TipoSize.ToUpper = "Larghezza".ToUpper Then
tempMultiplier = MaxPixel / currentwidth
ElseIf TipoSize.ToUpper = "Altezza".ToUpper Then
tempMultiplier = MaxPixel / currentheight
Else
If currentheight > currentwidth Then ' portrait
tempMultiplier = MaxPixel / currentheight
Else
tempMultiplier = MaxPixel / currentwidth
End If
End If
Dim NewSize As New Size(CInt(currentwidth * tempMultiplier), CInt(currentheight * tempMultiplier))
Return NewSize
End Function
Public Property WorkFile() As FileInfo
Get
Return _workFile
End Get
Set(value As FileInfo)
_workFile = value
End Set
End Property
Public Property DestDir() As DirectoryInfo
Get
Return _DestDir
End Get
Set(ByVal value As DirectoryInfo)
_DestDir = value
End Set
End Property
Public Property SourceDir() As DirectoryInfo
Get
Return _SourceDir
End Get
Set(ByVal value As DirectoryInfo)
_SourceDir = value
End Set
End Property
Public Property DestDirStart() As DirectoryInfo
Get
Return _DestDirStart
End Get
Set(ByVal value As DirectoryInfo)
_DestDirStart = value
End Set
End Property
Public Property NomeFileChild() As String
Get
Return _NomeFileChild
End Get
Set(ByVal value As String)
_NomeFileChild = value
End Set
End Property
End Class

View file

@ -1,13 +0,0 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>false</MySubMain>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<ApplicationType>1</ApplicationType>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View file

@ -1,9 +0,0 @@
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
<Assembly: AssemblyTrademark("")>
<Assembly: ComVisible(False)>
'Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi
<Assembly: Guid("ed2ef4c1-7f15-469d-9c14-182f2ebc21b5")>

View file

@ -1,63 +0,0 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'This class was auto-generated by the StronglyTypedResourceBuilder
'class via a tool like ResGen or Visual Studio.
'To add or remove a member, edit your .ResX file then rerun ResGen
'with the /str option, or rebuild your VS project.
'''<summary>
''' A strongly-typed resource class, for looking up localized strings, etc.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Returns the cached ResourceManager instance used by this class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("CatalogVbLib.Resources", GetType(Resources).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Overrides the current thread's CurrentUICulture property for all
''' resource lookups using this strongly typed resource class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
End Module
End Namespace

View file

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -1,73 +0,0 @@
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:4.0.30319.42000
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.11.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
#Region "My.Settings Auto-Save Functionality"
#If _MyType = "WindowsForms" Then
Private Shared addedHandler As Boolean
Private Shared addedHandlerLockObject As New Object
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
If My.Application.SaveMySettingsOnExit Then
My.Settings.Save()
End If
End Sub
#End If
#End Region
Public Shared ReadOnly Property [Default]() As MySettings
Get
#If _MyType = "WindowsForms" Then
If Not addedHandler Then
SyncLock addedHandlerLockObject
If Not addedHandler Then
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
addedHandler = True
End If
End SyncLock
End If
#End If
Return defaultInstance
End Get
End Property
End Class
End Namespace
Namespace My
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.CatalogVbLib.My.MySettings
Get
Return Global.CatalogVbLib.My.MySettings.Default
End Get
End Property
End Module
End Namespace

View file

@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View file

@ -1,606 +0,0 @@
Imports System.IO
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging
Imports System.Windows.Forms
Imports System.Drawing
Public Module PicSettings
Private _DirectorySorgente As String
Private _DirectoryDestinazione As String
Private _DimVert As Integer
Private _MargVert As Integer
Private _DimStandard As Integer
Private _DimStandardMiniatura As Integer
Private _NomeData As Boolean
Private _TestoNome As Boolean
Private _UsaOrarioMiniatura As Boolean
Private _UsaOrarioTestoApplicare As Boolean
Private _UsaTempoGaraTestoApplicare As Boolean
Private _TestoFirmaStart As String
Private _TestoFirmaStartV As String
Private _DataPartenza As DateTime
Private _TestoOrario As String
Private _UsaRotazioneAutomatica As Boolean
Private _UsaForzaJpg As Boolean
Private _LarghezzaSmall As Integer
Private _AltezzaSmall As Integer
Private _CreaMiniature As Boolean
Private _AggiungiScritteMiniature As Boolean
Private _AggTempoGaraMin As Boolean
Private _AggNumTempMin As Boolean
Private _Suffisso As String
Private _Codice As String
Private _Trasparenza As Integer
Private _IlFont As String
Private _Grassetto As Boolean
Private _Posizione As String
Private _Allineamento As String
Private _Margine As Integer
Private _LogoAltezza As Integer
Private _LogoLarghezza As Integer
Private _fontColoreRGB As System.Drawing.Color
Private _LogoAggiungi As Boolean
Private _LogoNomeFile As String
Private _LogoTrasparenza As String
Private _LogoMargine As String
Private _LogoPosizioneH As String
Private _LogoPosizioneV As String
Private _FotoGrandeDimOrigina As Boolean
Private _AltezzaBig As Integer
Private _LarghezzaBig As Integer
Private _DestDir As DirectoryInfo
Private _DimMin As Integer
Private _TestoMin As Boolean
Private _SecretDefault As Boolean
Private _SecretBig As Boolean
Private _SecretSmall As Boolean
Private _SecretPathSmall As String
Private _SecretPathBig As String
Private _jpegQuality As Long
Private _jpegQualityMin As Long
Private FotoRuotaADestra As Boolean = False
Private FotoRuotaASinistra As Boolean = False
Private TempMinText As String = ""
Private _mainForm As Form
'Private progressBar As System.Windows.Forms.ProgressBar
Public Property mainForm() As Form
Get
Return _mainForm
End Get
Set(ByVal value As Form)
_mainForm = value
End Set
End Property
Public Property DirectorySorgente() As String
Get
Return _DirectorySorgente
End Get
Set(ByVal value As String)
_DirectorySorgente = value
End Set
End Property
Public Property DirectoryDestinazione() As String
Get
Return _DirectoryDestinazione
End Get
Set(ByVal value As String)
_DirectoryDestinazione = value
End Set
End Property
Public Property TestoFirmaStart() As String
Get
Return _TestoFirmaStart
End Get
Set(ByVal value As String)
_TestoFirmaStart = value
End Set
End Property
Public Property TestoFirmaStartV() As String
Get
Return _TestoFirmaStartV
End Get
Set(ByVal value As String)
_TestoFirmaStartV = value
End Set
End Property
Public Property DataPartenza() As DateTime
Get
Return _DataPartenza
End Get
Set(ByVal value As DateTime)
_DataPartenza = value
End Set
End Property
Public Property TestoOrario() As String
Get
Return _TestoOrario
End Get
Set(ByVal value As String)
_TestoOrario = value
End Set
End Property
Public Property DimStandard() As Integer
Get
Return _DimStandard
End Get
Set(ByVal value As Integer)
_DimStandard = value
End Set
End Property
Public Property DimStandardMiniatura() As Integer
Get
Return _DimStandardMiniatura
End Get
Set(ByVal value As Integer)
_DimStandardMiniatura = value
End Set
End Property
Public Property NomeData() As Boolean
Get
Return _NomeData
End Get
Set(ByVal value As Boolean)
_NomeData = value
End Set
End Property
Public Property TestoNome() As Boolean
Get
Return _TestoNome
End Get
Set(ByVal value As Boolean)
_TestoNome = value
End Set
End Property
Public Property UsaOrarioMiniatura() As Boolean
Get
Return _UsaOrarioMiniatura
End Get
Set(ByVal value As Boolean)
_UsaOrarioMiniatura = value
End Set
End Property
Public Property UsaOrarioTestoApplicare() As Boolean
Get
Return _UsaOrarioTestoApplicare
End Get
Set(ByVal value As Boolean)
_UsaOrarioTestoApplicare = value
End Set
End Property
Public Property UsaTempoGaraTestoApplicare() As Boolean
Get
Return _UsaTempoGaraTestoApplicare
End Get
Set(ByVal value As Boolean)
_UsaTempoGaraTestoApplicare = value
End Set
End Property
Public Property UsaRotazioneAutomatica() As Boolean
Get
Return _UsaRotazioneAutomatica
End Get
Set(ByVal value As Boolean)
_UsaRotazioneAutomatica = value
End Set
End Property
Public Property UsaForzaJpg() As Boolean
Get
Return _UsaForzaJpg
End Get
Set(ByVal value As Boolean)
_UsaForzaJpg = value
End Set
End Property
Public Property LarghezzaSmall() As Integer
Get
Return _LarghezzaSmall
End Get
Set(ByVal value As Integer)
_LarghezzaSmall = value
End Set
End Property
Public Property AltezzaSmall() As Integer
Get
Return _AltezzaSmall
End Get
Set(ByVal value As Integer)
_AltezzaSmall = value
End Set
End Property
Public Property CreaMiniature() As Boolean
Get
Return _CreaMiniature
End Get
Set(ByVal value As Boolean)
_CreaMiniature = value
End Set
End Property
Public Property AggiungiScritteMiniature() As Boolean
Get
Return _AggiungiScritteMiniature
End Get
Set(ByVal value As Boolean)
_AggiungiScritteMiniature = value
End Set
End Property
Public Property Suffisso() As String
Get
Return _Suffisso
End Get
Set(ByVal value As String)
_Suffisso = value
End Set
End Property
Public Property Codice() As String
Get
Return _Codice
End Get
Set(ByVal value As String)
_Codice = value
End Set
End Property
Public Property Trasparenza() As Integer
Get
Return _Trasparenza
End Get
Set(ByVal value As Integer)
_Trasparenza = value
End Set
End Property
Public Property IlFont() As String
Get
Return _IlFont
End Get
Set(ByVal value As String)
_IlFont = value
End Set
End Property
Public Property Grassetto() As Boolean
Get
Return _Grassetto
End Get
Set(ByVal value As Boolean)
_Grassetto = value
End Set
End Property
Public Property Posizione() As String
Get
Return _Posizione
End Get
Set(ByVal value As String)
_Posizione = value
End Set
End Property
Public Property Allineamento() As String
Get
Return _Allineamento
End Get
Set(ByVal value As String)
_Allineamento = value
End Set
End Property
Public Property Margine() As Integer
Get
Return _Margine
End Get
Set(ByVal value As Integer)
_Margine = value
End Set
End Property
Public Property LogoAltezza() As Integer
Get
Return _LogoAltezza
End Get
Set(ByVal value As Integer)
_LogoAltezza = value
End Set
End Property
Public Property LogoLarghezza() As Integer
Get
Return _LogoLarghezza
End Get
Set(ByVal value As Integer)
_LogoLarghezza = value
End Set
End Property
Public Property fontColoreRGB() As Color
Get
Return _fontColoreRGB
End Get
Set(ByVal value As Color)
_fontColoreRGB = value
End Set
End Property
Public Property LogoAggiungi() As Boolean
Get
Return _LogoAggiungi
End Get
Set(ByVal value As Boolean)
_LogoAggiungi = value
End Set
End Property
Public Property LogoNomeFile() As String
Get
Return _LogoNomeFile
End Get
Set(ByVal value As String)
_LogoNomeFile = value
End Set
End Property
Public Property LogoTrasparenza() As String
Get
Return _LogoTrasparenza
End Get
Set(ByVal value As String)
_LogoTrasparenza = value
End Set
End Property
Public Property LogoMargine() As String
Get
Return _LogoMargine
End Get
Set(ByVal value As String)
_LogoMargine = value
End Set
End Property
Public Property LogoPosizioneH() As String
Get
Return _LogoPosizioneH
End Get
Set(ByVal value As String)
_LogoPosizioneH = value
End Set
End Property
Public Property LogoPosizioneV() As String
Get
Return _LogoPosizioneV
End Get
Set(ByVal value As String)
_LogoPosizioneV = value
End Set
End Property
Public Property FotoGrandeDimOrigina() As Boolean
Get
Return _FotoGrandeDimOrigina
End Get
Set(ByVal value As Boolean)
_FotoGrandeDimOrigina = value
End Set
End Property
Public Property AltezzaBig() As Integer
Get
Return _AltezzaBig
End Get
Set(ByVal value As Integer)
_AltezzaBig = value
End Set
End Property
Public Property LarghezzaBig() As Integer
Get
Return _LarghezzaBig
End Get
Set(ByVal value As Integer)
_LarghezzaBig = value
End Set
End Property
Public Property DestDir() As DirectoryInfo
Get
Return _DestDir
End Get
Set(ByVal value As DirectoryInfo)
_DestDir = value
End Set
End Property
Public Property DimVert() As Integer
Get
Return _DimVert
End Get
Set(ByVal value As Integer)
_DimVert = value
End Set
End Property
Public Property MargVert() As Integer
Get
Return _MargVert
End Get
Set(ByVal value As Integer)
_MargVert = value
End Set
End Property
Public Property TestoMin() As Boolean
Get
Return _TestoMin
End Get
Set(ByVal value As Boolean)
_TestoMin = value
End Set
End Property
Public Property DimMin() As Integer
Get
Return _DimMin
End Get
Set(ByVal value As Integer)
_DimMin = value
End Set
End Property
Public Property SecretDefault() As Boolean
Get
Return _SecretDefault
End Get
Set(ByVal value As Boolean)
_SecretDefault = value
End Set
End Property
Public Property SecretBig() As Boolean
Get
Return _SecretBig
End Get
Set(ByVal value As Boolean)
_SecretBig = value
End Set
End Property
Public Property SecretSmall() As Boolean
Get
Return _SecretSmall
End Get
Set(ByVal value As Boolean)
_SecretSmall = value
End Set
End Property
Public Property SecretPathSmall() As String
Get
Return _SecretPathSmall
End Get
Set(ByVal value As String)
_SecretPathSmall = value
End Set
End Property
Public Property SecretPathBig() As String
Get
Return _SecretPathBig
End Get
Set(ByVal value As String)
_SecretPathBig = value
End Set
End Property
Public Property AggTempoGaraMin() As Boolean
Get
Return _AggTempoGaraMin
End Get
Set(ByVal value As Boolean)
_AggTempoGaraMin = value
End Set
End Property
Public Property AggNumTempMin() As Boolean
Get
Return _AggNumTempMin
End Get
Set(ByVal value As Boolean)
_AggNumTempMin = value
End Set
End Property
Public Property jpegQuality() As Long
Get
Return _jpegQuality
End Get
Set(ByVal value As Long)
_jpegQuality = value
End Set
End Property
Public Property jpegQualityMin() As Long
Get
Return _jpegQualityMin
End Get
Set(ByVal value As Long)
_jpegQualityMin = value
End Set
End Property
End Module

7
GitVersion.yml Normal file
View file

@ -0,0 +1,7 @@
assembly-versioning-scheme: MajorMinorPatch
mode: ContinuousDelivery
branches: {}
ignore:
sha: []
merge-message-formats: {}
next-version: "3.2.0"

View file

@ -1,101 +0,0 @@
namespace ImageCatalogCS
{
partial class AboutForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm));
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 213);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(75, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Image Catalog";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(350, 213);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(66, 13);
this.label2.TabIndex = 1;
this.label2.Text = "Versione 3.0";
//
// button1
//
this.button1.Location = new System.Drawing.Point(176, 239);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 2;
this.button1.Text = "Chiudi";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.InitialImage = ((System.Drawing.Image)(resources.GetObject("pictureBox1.InitialImage")));
this.pictureBox1.Location = new System.Drawing.Point(15, 13);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(401, 197);
this.pictureBox1.TabIndex = 3;
this.pictureBox1.TabStop = false;
//
// AboutForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(433, 274);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.button1);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Name = "AboutForm";
this.Text = "AboutForm";
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.PictureBox pictureBox1;
}
}

View file

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ImageCatalogCS
{
public partial class AboutForm : Form
{
public AboutForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
}
}

View file

@ -1,229 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="pictureBox1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAZ4AAADQCAIAAAC4O5DwAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAS
cwAAEnMBjCK5BwAAC05JREFUeF7t2sGBG0cORmEn4PPmooCUxO7FGTgaJ+NgtE0OKZMeTTdQDVQBf7/v
4svuDLsK9boo6bcfACCHtAEQRNoACCJtAASRNgCCSBsAQaQNgCDSBkAQaQMgiLQBEETaAAgibQAEkTYA
gkgbAEGkDYAg0gZAEGkDIIi0ARBE2gAIIm0ABJE2AIJIGwBBpA2AINIGQBBpAyCItAEQRNoACCJtAASR
NgCCSBsAQaQNgCDSBkAQaQMgiLQBEETaAAgibQAEkTYAgkgbAEGkDYAg0pbqr++/Dfn259+PnwBhjEci
0hZndFBtvv/1+DXoifGYi7SdkzuvX+Gt3QTjsQ5pG/H3n98eU7QaL+uCGI8KSJtHnZn9NxJXAONRCWkz
qTu0b/gmsgbjUdDKtB0PRIG9aDK1r1asmvsPlUSO2cXGo8WRfViXNsNQLL5GNxzbF3MX74Jpu+Z4HG90
lZ1dlTbLXCwsW+7YHm5+2F+sTVvCa6UtvWr7q7N0PAy/vMberkmbZTSWrU/Y4OxyTtWJDzUlb9dJ25zx
2Hj2beZ4lD68L1akzfTOm3IgP5k2tzeD+z9yZUgftWukbep4bEYWacJ4WJZh/f7OT5tt6ReUbfbc3px6
TOcQpy6pftpWjMdmfNcSx8O0Fqt3eHbabOs9fVVGXnUxAh7Vfujy1lU7bevGY3N2pTLGo+gxfjM5bbZl
nrwkSwd3E3Odsk5wzuVNOG3G8fjP478ZAvYsejxsPy9n2Gymps24vFPXwzS4vz/+myTumNuOYcICq6bN
tKDf/vff5Jdj0GpFjkfFw/xmYtqMb7+ZM2/5SN//sJ7az7toPvChD234reGLLJk203hsm25++BITEjUe
Bc/zm2lpMy7EzJU43uNtFE2fe/9DW8Y3+rGPP3bsbzQf0adlE29mGo9NxwkJGY+CR/rVrLRZR3/aMhzu
i3VuTZ/YMAWf3+hnHa554K9US5txPCz/y6oTEjAe1l2Pn22DOWkz7NuHWWtwtCfPz2Gf8ENHPyrlrB/9
0rD11kqbdTw2rSfk9HhYt33Fbk9Jm3nuw07avv3P87INsWU4+GlZ229+2jPMW/y0YtiNPAvWf0LOjYd5
3ycd7RcT0na0+z/Nmfb9j/P+GaKrsP/z8nZ/9/eGLLt5xJ/mbLafZzw2EhNyZjyKne4X+WkzD/2UZ9/d
iX9/gv1tG5mzM0N0iuu5B5h3+Wn6pJt4l0llQk6Mx/4SvJp8cctOm/3BC876iQ3/QvxRKEIkbV5MSN0j
npw2+8RXHPWEN+jujyRt3TAhG3vbpn7+1LQVfWYzBteMtH12nQmx7/7Ebc9MW/ey7T/A0CbtLwlp64YJ
+eDY/mmPkJi2io/rEz9mu2vS+bSTtl+40IQUPOx5aetftqNn8A/a/s8ruwwGjt3+oJE2JuTJMQCTtj4r
bfuvs3d1N+zoKXyf/OCntT7sV00bE/JUrm1JadMom+E57B8+8EcV5E7bh9bPfMeEPFVrW07aPINe+/V9
3GjT5z/+Mc1P+WDafur79EzIk2cGJjxLStp0ymYauaOHsCxH9WU4cjZtH1quAhPyYFqIp/y2ZaRNqWwb
8+N83i3z/7V72YLSdtdvLZiQD7XalpA2z5S3GGPXjo1oH7bQtN1N+MISiAn5UKpt8WlzDXmTCc4d3V7H
+Nei03bTaV2YkLtKhz88bYpl26SNrsCN7SYjbZtGq8OE3BQ6/tFpcz1ar2OdcXo7XUx2JaVt02hImBBn
4FMfLjhtwmXbBL+Y2z3/jry0bS57uW84IXXaFpu2Qs3OEnWGWz7811LT1uuMX3xCytxuQtPmK1vbS8vp
V7PSde0hOW3N1uzKE1ImAqFp881373vL6FkWu609paet33G/6oRUqUBk2nzPJHF18TyyaNQ+TEhbz5G5
3oQ4r6xpDx2Ytot8Hf21rydY7EG/8Hz+naeNqF/jw3+dCfFtdNrTB6bN90TSdxh87dyfQ13jRdFbkWtb
XNoufWmDz4kbHO/E8py7m7SjcWkrcg1FE8N1o23VOa9tSS0IS1uRWyj6GP1qymuxuhLXtrC0cWmD39jV
jekprsS1LSptXNowYuzmxvgUV+HaFpW2EldQNDR0cWN+ahNKW4kbKFoaaRsDVFuFHgSlzTmeTCb+Qdvk
eP+cIePatiZtfJ/Ai5G2MUKlFQhCTNoqRBptjfxdAte20gp8jVuSNsYSb0baxuuxsgJFIG0oYOArKWmr
zPuyStjNmLQVuH6is4G0MUSVXTVtvHDxbuAbKWmrjLQBd3wjFbM+CaQNFZA2Mc4NTbiDkzZUQNrEkDbg
hrSJIW3ADWkTsz4JpA0V+NPG35CWRtqAG9KmhX+yC9wM/Ls23o+VOTc0owgxaSvwIOiMtIkhbcAN30fF
OIuQ8Z6KSRt/2IYzuLSpKRAE0ob1uLSp8e1oym4GpY1vpFfyc7eDXlH+svFyrK1CD4LSVqHSyPLl5sbs
I2WTU+CP2sLSVuFZEMOxlxFtGygbr8biKtx0otLmfBjSVtGKyDjfiXeUrbgSF52wtPmehuEsaX7bBn4j
w1NeiRiEpY1rm4LJd6iRsDE69ZVoQVzauLYpGGnb4GYO/SrK1kCNFMSljWubhMHgeOdz6L624ZXYQI0S
BKaNa5uG0epYt3Qwnne8EBvwbXDalgamrcoj4aQz7dl8WbjhZj7xOmzBtc95exqZtirPhLNORygDA9ND
lRtOaNq4tskoFzfC1oVrdBIjEJo2X9sY1tJKxY1ZaaNMA2LT5nsurm21+S7hiRiURjyvxNQ3VnDaytxG
EaLA1Y0LWyt1AhCdtjrRRoi1VzcmpJlCX9vC0+ZqG9e2DlbVjenop9Dpj08bbVM0O29c11qqdPYT0uZ5
Pia4kVl5433XlWdC0nc5I220TVhu36haZ57ZyD/4KWnztI1h7ig8cLziBNQ69jlpo20XcTpxJE1HsUOf
lDbHYzLcKoydY8M1OV5zU64zWWmjbcCVVCtbXtocj0rbgObKlS0xbbStiN19EF76qz73EgUPe2LaHF9K
GbRU+3Onufi7s8e8RSt41FPTRtvK2N8JteW/1tMWYD7oE/89RG7a7PdUxi3b0fRNHLpURyOn8pyVVCxb
dtrsT03b0h2+Z/qf+sNpI2wJap7x9LTRtkqON6Pv2T/+hsCIZTB/M5s8WvlpMz86gzeDZTf65c3w/mS8
cpQ93hPSZr+48W1hCtMwtimB7WgxWkmsZZu/AVPSVvj5L8q4IcX7xitzOeMWrBikOWkrvQQXZX3dlCyD
NWpMVC7jPiyZoFlpE7kniLEXosjO2Ht8x3UtVe0zPS1t5oVgHOfy5O1mxaA6i3bHSzJb8QM9MW3WU0Tb
pvPm7SG3HoMf6oYRmqD6aZ6aNmPned+uMHIz+mx4kk+E7B1Zm8O0YSuP8ty0GQ8QbVslpm+rULVpbIOy
dENmp81Ye4Z0oYZ942U4V4dDPD9ttnVhVldrEjgGZT7TaCy/naxImy1uXNxKqFs4BmQRy0gUeOOsSZsp
boxuJXUSx1ysZTi6Ja7Sq9JmWSG+a5RkuXLHYxhqMLziimzVurRZzggv6OJyM8f2l9PoQrIybVA0Wjuu
ZQhF2gAIIm0ABJE2AIJIGwBBpA2AINIGQBBpAyCItAEQRNoACCJtAASRNgCCSBsAQaQNgCDSBkAQaQMg
iLQBEETaAAgibQAEkTYAgkgbAEGkDYAg0gZAEGkDIIi0ARBE2gAIIm0ABJE2AIJIGwBBpA2AINIGQBBp
AyCItAEQRNoACCJtAASRNgCCSBsAQaQNgCDSBkAQaQMgiLQBEETaAAgibQAEkTYAgkgbAEGkDYAg0gZA
EGkDIIi0ARBE2gAIIm0ABJE2AIJIGwA5P378HyuEmb0husDDAAAAAElFTkSuQmCC
</value>
</data>
<data name="pictureBox1.InitialImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAZ4AAADQCAIAAAC4O5DwAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAS
cwAAEnMBjCK5BwAAC05JREFUeF7t2sGBG0cORmEn4PPmooCUxO7FGTgaJ+NgtE0OKZMeTTdQDVQBf7/v
4svuDLsK9boo6bcfACCHtAEQRNoACCJtAASRNgCCSBsAQaQNgCDSBkAQaQMgiLQBEETaAAgibQAEkTYA
gkgbAEGkDYAg0gZAEGkDIIi0ARBE2gAIIm0ABJE2AIJIGwBBpA2AINIGQBBpAyCItAEQRNoACCJtAASR
NgCCSBsAQaQNgCDSBkAQaQMgiLQBEETaAAgibQAEkTYAgkgbAEGkDYAg0pbqr++/Dfn259+PnwBhjEci
0hZndFBtvv/1+DXoifGYi7SdkzuvX+Gt3QTjsQ5pG/H3n98eU7QaL+uCGI8KSJtHnZn9NxJXAONRCWkz
qTu0b/gmsgbjUdDKtB0PRIG9aDK1r1asmvsPlUSO2cXGo8WRfViXNsNQLL5GNxzbF3MX74Jpu+Z4HG90
lZ1dlTbLXCwsW+7YHm5+2F+sTVvCa6UtvWr7q7N0PAy/vMberkmbZTSWrU/Y4OxyTtWJDzUlb9dJ25zx
2Hj2beZ4lD68L1akzfTOm3IgP5k2tzeD+z9yZUgftWukbep4bEYWacJ4WJZh/f7OT5tt6ReUbfbc3px6
TOcQpy6pftpWjMdmfNcSx8O0Fqt3eHbabOs9fVVGXnUxAh7Vfujy1lU7bevGY3N2pTLGo+gxfjM5bbZl
nrwkSwd3E3Odsk5wzuVNOG3G8fjP478ZAvYsejxsPy9n2Gymps24vFPXwzS4vz/+myTumNuOYcICq6bN
tKDf/vff5Jdj0GpFjkfFw/xmYtqMb7+ZM2/5SN//sJ7az7toPvChD234reGLLJk203hsm25++BITEjUe
Bc/zm2lpMy7EzJU43uNtFE2fe/9DW8Y3+rGPP3bsbzQf0adlE29mGo9NxwkJGY+CR/rVrLRZR3/aMhzu
i3VuTZ/YMAWf3+hnHa554K9US5txPCz/y6oTEjAe1l2Pn22DOWkz7NuHWWtwtCfPz2Gf8ENHPyrlrB/9
0rD11kqbdTw2rSfk9HhYt33Fbk9Jm3nuw07avv3P87INsWU4+GlZ229+2jPMW/y0YtiNPAvWf0LOjYd5
3ycd7RcT0na0+z/Nmfb9j/P+GaKrsP/z8nZ/9/eGLLt5xJ/mbLafZzw2EhNyZjyKne4X+WkzD/2UZ9/d
iX9/gv1tG5mzM0N0iuu5B5h3+Wn6pJt4l0llQk6Mx/4SvJp8cctOm/3BC876iQ3/QvxRKEIkbV5MSN0j
npw2+8RXHPWEN+jujyRt3TAhG3vbpn7+1LQVfWYzBteMtH12nQmx7/7Ebc9MW/ey7T/A0CbtLwlp64YJ
+eDY/mmPkJi2io/rEz9mu2vS+bSTtl+40IQUPOx5aetftqNn8A/a/s8ruwwGjt3+oJE2JuTJMQCTtj4r
bfuvs3d1N+zoKXyf/OCntT7sV00bE/JUrm1JadMom+E57B8+8EcV5E7bh9bPfMeEPFVrW07aPINe+/V9
3GjT5z/+Mc1P+WDafur79EzIk2cGJjxLStp0ymYauaOHsCxH9WU4cjZtH1quAhPyYFqIp/y2ZaRNqWwb
8+N83i3z/7V72YLSdtdvLZiQD7XalpA2z5S3GGPXjo1oH7bQtN1N+MISiAn5UKpt8WlzDXmTCc4d3V7H
+Nei03bTaV2YkLtKhz88bYpl26SNrsCN7SYjbZtGq8OE3BQ6/tFpcz1ar2OdcXo7XUx2JaVt02hImBBn
4FMfLjhtwmXbBL+Y2z3/jry0bS57uW84IXXaFpu2Qs3OEnWGWz7811LT1uuMX3xCytxuQtPmK1vbS8vp
V7PSde0hOW3N1uzKE1ImAqFp881373vL6FkWu609paet33G/6oRUqUBk2nzPJHF18TyyaNQ+TEhbz5G5
3oQ4r6xpDx2Ytot8Hf21rydY7EG/8Hz+naeNqF/jw3+dCfFtdNrTB6bN90TSdxh87dyfQ13jRdFbkWtb
XNoufWmDz4kbHO/E8py7m7SjcWkrcg1FE8N1o23VOa9tSS0IS1uRWyj6GP1qymuxuhLXtrC0cWmD39jV
jekprsS1LSptXNowYuzmxvgUV+HaFpW2EldQNDR0cWN+ahNKW4kbKFoaaRsDVFuFHgSlzTmeTCb+Qdvk
eP+cIePatiZtfJ/Ai5G2MUKlFQhCTNoqRBptjfxdAte20gp8jVuSNsYSb0baxuuxsgJFIG0oYOArKWmr
zPuyStjNmLQVuH6is4G0MUSVXTVtvHDxbuAbKWmrjLQBd3wjFbM+CaQNFZA2Mc4NTbiDkzZUQNrEkDbg
hrSJIW3ADWkTsz4JpA0V+NPG35CWRtqAG9KmhX+yC9wM/Ls23o+VOTc0owgxaSvwIOiMtIkhbcAN30fF
OIuQ8Z6KSRt/2IYzuLSpKRAE0ob1uLSp8e1oym4GpY1vpFfyc7eDXlH+svFyrK1CD4LSVqHSyPLl5sbs
I2WTU+CP2sLSVuFZEMOxlxFtGygbr8biKtx0otLmfBjSVtGKyDjfiXeUrbgSF52wtPmehuEsaX7bBn4j
w1NeiRiEpY1rm4LJd6iRsDE69ZVoQVzauLYpGGnb4GYO/SrK1kCNFMSljWubhMHgeOdz6L624ZXYQI0S
BKaNa5uG0epYt3Qwnne8EBvwbXDalgamrcoj4aQz7dl8WbjhZj7xOmzBtc95exqZtirPhLNORygDA9ND
lRtOaNq4tskoFzfC1oVrdBIjEJo2X9sY1tJKxY1ZaaNMA2LT5nsurm21+S7hiRiURjyvxNQ3VnDaytxG
EaLA1Y0LWyt1AhCdtjrRRoi1VzcmpJlCX9vC0+ZqG9e2DlbVjenop9Dpj08bbVM0O29c11qqdPYT0uZ5
Pia4kVl5433XlWdC0nc5I220TVhu36haZ57ZyD/4KWnztI1h7ig8cLziBNQ69jlpo20XcTpxJE1HsUOf
lDbHYzLcKoydY8M1OV5zU64zWWmjbcCVVCtbXtocj0rbgObKlS0xbbStiN19EF76qz73EgUPe2LaHF9K
GbRU+3Onufi7s8e8RSt41FPTRtvK2N8JteW/1tMWYD7oE/89RG7a7PdUxi3b0fRNHLpURyOn8pyVVCxb
dtrsT03b0h2+Z/qf+sNpI2wJap7x9LTRtkqON6Pv2T/+hsCIZTB/M5s8WvlpMz86gzeDZTf65c3w/mS8
cpQ93hPSZr+48W1hCtMwtimB7WgxWkmsZZu/AVPSVvj5L8q4IcX7xitzOeMWrBikOWkrvQQXZX3dlCyD
NWpMVC7jPiyZoFlpE7kniLEXosjO2Ht8x3UtVe0zPS1t5oVgHOfy5O1mxaA6i3bHSzJb8QM9MW3WU0Tb
pvPm7SG3HoMf6oYRmqD6aZ6aNmPned+uMHIz+mx4kk+E7B1Zm8O0YSuP8ty0GQ8QbVslpm+rULVpbIOy
dENmp81Ye4Z0oYZ942U4V4dDPD9ttnVhVldrEjgGZT7TaCy/naxImy1uXNxKqFs4BmQRy0gUeOOsSZsp
boxuJXUSx1ysZTi6Ja7Sq9JmWSG+a5RkuXLHYxhqMLziimzVurRZzggv6OJyM8f2l9PoQrIybVA0Wjuu
ZQhF2gAIIm0ABJE2AIJIGwBBpA2AINIGQBBpAyCItAEQRNoACCJtAASRNgCCSBsAQaQNgCDSBkAQaQMg
iLQBEETaAAgibQAEkTYAgkgbAEGkDYAg0gZAEGkDIIi0ARBE2gAIIm0ABJE2AIJIGwBBpA2AINIGQBBp
AyCItAEQRNoACCJtAASRNgCCSBsAQaQNgCDSBkAQaQMgiLQBEETaAAgibQAEkTYAgkgbAEGkDYAg0gZA
EGkDIIi0ARBE2gAIIm0ABJE2AIJIGwA5P378HyuEmb0husDDAAAAAElFTkSuQmCC
</value>
</data>
</root>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
</configuration>

View file

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ImageCatalogCS
{
class CreaImmagineSeparateThread
{
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,173 +0,0 @@
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
public class FileHelper
{
//Private dirSourceDest As Dictionary(Of FileInfo, DirectoryInfo)
private int filesPerFolder;
private string suffix;
private int counterSize;
private int numerationType;
private string filter;
private bool separateFiles;
private string extensions = "*.jpg,*.png,*.gif";
public enum numerazione
{
Progressiva,
Files
}
/// <summary>
/// Preparazione per la separazione
/// </summary>
/// <param name="filesPerFolder"></param>
/// <param name="suffix"></param>
/// <param name="counterSize"></param>
/// <param name="numerationType"></param>
/// <remarks></remarks>
public FileHelper(int filesPerFolder, string suffix, int counterSize, int numerationType)
{
this.filesPerFolder = filesPerFolder;
this.suffix = suffix;
this.counterSize = counterSize;
this.numerationType = numerationType;
this.separateFiles = true;
}
/// <summary>
/// nessuna separazione
/// </summary>
/// <remarks></remarks>
public FileHelper()
{
this.separateFiles = false;
}
public Dictionary<FileInfo, DirectoryInfo> GetFilesRecursive(DirectoryInfo root, DirectoryInfo destRoot, string filter)
{
Dictionary<FileInfo, DirectoryInfo> dirSourceDest = new Dictionary<FileInfo, DirectoryInfo>();
List<FileInfo> result = new List<FileInfo>();
//Dim stack As New Stack(Of DirectoryInfo)
Stack<KeyValuePair<DirectoryInfo, DirectoryInfo>> stack = new Stack<KeyValuePair<DirectoryInfo, DirectoryInfo>>();
this.filter = filter;
KeyValuePair<DirectoryInfo, DirectoryInfo> pair = new KeyValuePair<DirectoryInfo, DirectoryInfo>();
//stack.Push(root)
stack.Push(new KeyValuePair<DirectoryInfo, DirectoryInfo>(root, destRoot));
while ((stack.Count > 0))
{
KeyValuePair<DirectoryInfo, DirectoryInfo> curDirKV = stack.Pop();
//curDirKP = stack.Pop()
DirectoryInfo dir = curDirKV.Key;
DirectoryInfo dDir = curDirKV.Value;
try
{
//result.AddRange(dir.GetFiles(filter, SearchOption.TopDirectoryOnly))
// dividere file qui
if (filesPerFolder > 0 & separateFiles)
{
appendDictionary(dirSourceDest, dividiFilesInDir(dir, dDir));
}
else
{
appendDictionary(dirSourceDest, getAllFilesInDir(dir, dDir));
}
foreach (DirectoryInfo subDirectory in dir.GetDirectories())
{
stack.Push(new KeyValuePair<DirectoryInfo, DirectoryInfo>(subDirectory, new DirectoryInfo(Path.Combine(dDir.FullName, subDirectory.Name))));
}
}
catch (Exception ex)
{
}
}
return dirSourceDest;
}
public Dictionary<FileInfo, DirectoryInfo> appendDictionary(Dictionary<FileInfo, DirectoryInfo> dictA, Dictionary<FileInfo, DirectoryInfo> dictB)
{
foreach (KeyValuePair<FileInfo, DirectoryInfo> pair in dictB)
{
dictA.Add(pair.Key, pair.Value);
}
return dictA;
}
public Dictionary<FileInfo, DirectoryInfo> getAllFilesInDir(DirectoryInfo dir, DirectoryInfo dirDest)
{
Dictionary<FileInfo, DirectoryInfo> dict = new Dictionary<FileInfo, DirectoryInfo>();
foreach (FileInfo File in dir.GetFiles(filter))
{
dict.Add(File, new DirectoryInfo(Path.Combine(dirDest.FullName, File.Name)));
}
return dict;
}
private Dictionary<FileInfo, DirectoryInfo> dividiFilesInDir(DirectoryInfo dir, DirectoryInfo dirDest)
{
int filesCount = dir.GetFiles(filter).Length;
int contaFilePerDir = 0;
int contaDirPerDir = 0;
string tempText = string.Empty;
Dictionary<FileInfo, DirectoryInfo> foldersDict = new Dictionary<FileInfo, DirectoryInfo>();
DirectoryInfo destDir = null;
destDir = new DirectoryInfo(Path.Combine(dirDest.FullName));
foreach (FileInfo file in dir.GetFiles(filter))
{
contaFilePerDir += 1;
if (contaFilePerDir == (contaDirPerDir * filesPerFolder) + 1)
{
contaDirPerDir += 1;
if (numerazione.Progressiva.Equals(numerationType))
{
tempText = contaDirPerDir.ToString();
}
else
{
tempText = (contaDirPerDir * filesPerFolder).ToString();
}
int i = 0;
for (i = 1; i <= (counterSize - tempText.Length); i++)
{
tempText = "0" + tempText;
}
destDir = new DirectoryInfo(Path.Combine(dirDest.FullName, suffix + tempText));
}
if (!destDir.Exists)
{
destDir.Create();
}
foldersDict.Add(file, destDir);
}
return foldersDict;
}
}

View file

@ -1,132 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D11ED7B0-93E8-4F38-A142-EED72D7EE8B5}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ImageCatalogCS</RootNamespace>
<AssemblyName>ImageCatalogCS</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Management" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AboutForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="AboutForm.Designer.cs">
<DependentUpon>AboutForm.cs</DependentUpon>
</Compile>
<Compile Include="CreaImmagineSeparateThread.cs" />
<Compile Include="ExifReader.cs" />
<Compile Include="FileHelper.cs" />
<Compile Include="ImageCreator.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="PicSettings.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Temperature.cs" />
<Compile Include="XMLSettings.cs" />
<Compile Include="XYThreadPool.cs" />
<EmbeddedResource Include="AboutForm.resx">
<DependentUpon>AboutForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,548 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Text;
using System.Threading;
public delegate void XyThreadAdd(string Info);
namespace ImageCatalogCS
{
public partial class MainForm : Form
{
private bool stopAttivo;
private bool waterSelectColor = false;
//pool
private XYThreadPool myPool = new XYThreadPool();
private int contaImmaginiThread;
private int maxThreads = 15;
private int minThreads = 5;
public MainForm()
{
InitializeComponent();
}
private void setDefaults()
{
txtSorgente.Text = "";
txtDestinazione.Text = "";
TextBox3.Text = "tn_";
TextBox4.Text = "";
TextBox5.Text = "350";
TextBox6.Text = "350";
TextBox27.Text = "2240";
TextBox28.Text = "2240";
TextBox9.Text = "0";
TextBox11.Text = "20";
TextBox12.Text = "8";
//TextBox13.Text = ""
TextBox10.Text = "";
TextBox14.Text = "430";
TextBox15.Text = "430";
TextBox16.Text = "290";
txtFilePerCartella.Text = "99";
TextBox19.Text = "100";
txtSuffissoCartelle.Text = "";
txtCifreContatore.Text = "2";
TextBox25.Text = "50";
TextBox26.Text = "";
TextBox7.Text = Convert.ToString(15);
TextBox8.Text = Convert.ToString(5);
TextBox34.Text = "Yellow";
TextBox30.Text = "20";
TextBox31.Text = "6";
TextBox32.Text = "85";
TextBox33.Text = "30";
ComboBox1.Items.Add("Alto");
ComboBox1.Items.Add("Basso");
ComboBox1.SelectedIndex = 1;
ComboBox2.Items.Add("Sinistra");
ComboBox2.Items.Add("Centro");
ComboBox2.Items.Add("Destra");
ComboBox2.SelectedIndex = 1;
// Create a obejct of InstalledFontCollection
InstalledFontCollection InstalledFonts = new InstalledFontCollection();
// Gets the array of FontFamily objects associated with this FontCollection.
FontFamily[] fontfamilies = InstalledFonts.Families;
// Populates font combobox with the font name
foreach (FontFamily fontFamily in fontfamilies)
{
ComboBox3.Items.Add(fontFamily.Name);
}
ComboBox3.Text = ComboBox3.Items[0].ToString();
ComboBox4.Items.Add("Sinistra");
ComboBox4.Items.Add("Centro");
ComboBox4.Items.Add("Destra");
ComboBox4.SelectedIndex = 2;
ComboBox5.Items.Add("Alto");
ComboBox5.Items.Add("Centro");
ComboBox5.Items.Add("Basso");
ComboBox5.SelectedIndex = 2;
}
private void Form1_Load(object sender, EventArgs e)
{
Application.EnableVisualStyles();
setDefaults();
}
private void btnCreaCatalogo_Click(object sender, EventArgs e)
{
DateTime timestart;
DateTime timeStop;
timestart = DateTime.Now;
txtFileInfo.Text = string.Empty;
lblFotoTotaliNum.Text = "0";
Label18.Text = "0";
Label43.Text = "-s";
maxThreads = Convert.ToInt32(TextBox7.Text);
minThreads = Convert.ToInt32(TextBox18.Text);
//setPicSettings(txtSorgente.Text, txtDestinazione.Text);
makeSettingsFromForm();
ProgressBar1.Minimum = 0;
ProgressBar1.Step = 1;
ProgressBar1.Value = 0;
System.Threading.Thread t1 = new System.Threading.Thread(creaCatalogoThread);
}
private void creaCatalogoThread()
{
System.DateTime timeStart = DateTime.Now;
myPool.StopThreadPool();
myPool.StartThreadPool(minThreads, maxThreads);
contaImmaginiThread = 0;
//creaImmaginiWithThreadMod(txtSorgente.Text, txtDestinazione.Text)
//creaimmaginiWithThreadDict(txtSorgente.Text, txtDestinazione.Text);
ThreadPoolWorkItem ThAttivo = null;
//int i = 0;
// fine
}
private int getNumerazione()
{
int numerazione = 0;
if (rdbNumProgressiva.Checked)
{
numerazione = (int)FileHelper.numerazione.Progressiva;
}
else
{
numerazione = (int)FileHelper.numerazione.Files;
}
return numerazione;
}
private void creaimmaginiWithThreadDict(string SourcePath, string DestPath)
{
Dictionary<FileInfo, DirectoryInfo> dirSourceDest = new Dictionary<FileInfo, DirectoryInfo>();
if (chkAggiornaSottodirectory.Checked & chkCreaSottocartelle.Checked) {
FileHelper helper = new FileHelper(Convert.ToInt32(txtFilePerCartella.Text), txtSuffissoCartelle.Text, Convert.ToInt32(txtCifreContatore.Text), getNumerazione());
//getfilesrecursive
dirSourceDest = helper.GetFilesRecursive(new DirectoryInfo(SourcePath), new DirectoryInfo(DestPath), "*.jpg");
} else if (chkAggiornaSottodirectory.Checked & !chkCreaSottocartelle.Checked) {
}
//else if ()
//= getDirsDict(SourcePath, DestPath)
KeyValuePair<FileInfo, DirectoryInfo> pair = default(KeyValuePair<FileInfo, DirectoryInfo>);
foreach (KeyValuePair<FileInfo, DirectoryInfo> pair_loopVariable in dirSourceDest) {
pair = pair_loopVariable;
//setLabel10Text("File: " + pair.Key.Name);
string b = (Convert.ToInt32(Label18.Text) + 1).ToString();
ImageCreator ClsCreaImmagine = new ImageCreator(pair.Key, pair.Value);
contaImmaginiThread += 1;
myPool.InsertWorkItem(pair.Key.Name, new XyThreadAdd(ClsCreaImmagine.CreaImmagineThread), new object[1] { pair.Key.Name }, true);
}
}
private Dictionary<string, object> makeSettingsFromForm()
{
Dictionary<string, object> settingsDict = new Dictionary<string, object>();
settingsDict.Add("sourceDirRoot", new DirectoryInfo(txtSorgente.Text));
settingsDict.Add("destDirRoot", new DirectoryInfo(txtDestinazione.Text));
settingsDict.Add("DirDividiDestinazione", chkCreaSottocartelle.Checked);
settingsDict.Add("DirDividiNumFile", txtFilePerCartella.Text);
settingsDict.Add("DirDividiSuffisso", txtSuffissoCartelle.Text);
settingsDict.Add("DirDividiNumCifre", txtCifreContatore.Text);
settingsDict.Add("DirDividiTipoNumerazione", rdbNumProgressiva.Checked ? "Progressiva" : "Files");
// if (rdbNumProgressiva.Checked)
// settingsDict.Add("DirDividiTipoNumerazione", "Progressiva");
//else
// settingsDict.Add("DirDividiTipoNumerazione", "Files");
// Checkbox
settingsDict.Add("creaMiniature", CheckBox1.Checked);
settingsDict.Add("aggiungiTesto", CheckBox2.Checked);
settingsDict.Add("grassetto", CheckBox3.Checked);
settingsDict.Add("logoAggiungi", CheckBox5.Checked);
settingsDict.Add("usaOrarioTestoApplicare", CheckBox8.Checked);
//settingsDict.Add("usaOrarioMiniatura", CheckBox12.Checked);
settingsDict.Add("fotoGrandeDimOrigina", CheckBox15.Checked);
settingsDict.Add("dimStandard", Convert.ToInt32(TextBox11.Text));
settingsDict.Add("dimStandardMiniatura", Convert.ToInt32(TextBox25.Text));
settingsDict.Add("usaRotazioneAutomatica", chkRotazioneAutomatica.Checked);
settingsDict.Add("usaForzaJpg", chkForzaJpg.Checked);
settingsDict.Add("testoNome", CheckBox17.Checked);
settingsDict.Add("nomeData", CheckBox16.Checked);
settingsDict.Add("testoFirmaStart", TextBox4.Text);
settingsDict.Add("testoFirmaStartV", TextBox29.Text);
settingsDict.Add("dataPartenza", DateTimePicker1.Value);
settingsDict.Add("testoOrario", TextBox18.Text);
settingsDict.Add("altezzaSmall", Convert.ToInt32(TextBox6.Text));
settingsDict.Add("larghezzaSmall", Convert.ToInt32(TextBox5.Text));
settingsDict.Add("aggiungiScritteMiniature", RadioButton3.Checked);
settingsDict.Add("aggTempoGaraMin", RadioButton5.Checked);
settingsDict.Add("aggNumTempMin", RadioButton7.Checked);
settingsDict.Add("dimVert", Convert.ToUInt32(TextBox30.Text));
settingsDict.Add("margVert", Convert.ToInt32(TextBox31.Text));
settingsDict.Add("suffisso", TextBox3.Text);
settingsDict.Add("trasparenza", Convert.ToInt32(TextBox9.Text));
settingsDict.Add("ilFont", ComboBox3.SelectedItem.ToString());
settingsDict.Add("posizione", ComboBox1.SelectedItem.ToString());
settingsDict.Add("allineamento", ComboBox2.SelectedItem.ToString());
settingsDict.Add("margine", Convert.ToInt32(TextBox12.Text));
settingsDict.Add("logoAltezza", Convert.ToInt32(TextBox14.Text));
settingsDict.Add("logoLarghezza", Convert.ToInt32(TextBox15.Text));
settingsDict.Add("fontColoreRGB", ColorTranslator.FromHtml(TextBox34.Text));
settingsDict.Add("logoNomeFile", TextBox10.Text);
settingsDict.Add("logoTrasparenza", TextBox19.Text);
settingsDict.Add("logoMargine", TextBox16.Text);
settingsDict.Add("logoPosizioneH", ComboBox4.Text);
settingsDict.Add("logoPosizioneV", ComboBox5.Text);
settingsDict.Add("altezzaBig", Convert.ToInt32(TextBox27.Text));
settingsDict.Add("larghezzaBig", Convert.ToInt32(TextBox28.Text));
settingsDict.Add("dimMin", Convert.ToInt32(TextBox25.Text));
settingsDict.Add("testoMin", RadioButton6.Checked);
settingsDict.Add("jpegQuality", Convert.ToInt32(TextBox32.Text));
settingsDict.Add("jpegQualityMin", Convert.ToInt32(TextBox33.Text));
return settingsDict;
}
private void setPicSettings(string SourcePath, string DestPath)
{
DirectoryInfo SourceDir = new DirectoryInfo(SourcePath);
DirectoryInfo DestDirStart = new DirectoryInfo(DestPath);
DirectoryInfo DestDir = null;
PicSettings.directorySorgente = txtSorgente.Text;
PicSettings.directoryDestinazione = txtDestinazione.Text;
PicSettings.dimStandard = Convert.ToInt32(TextBox11.Text);
PicSettings.dimStandardMiniatura = Convert.ToInt32(TextBox25.Text);
//PicSettings.UsaOrarioMiniatura = CheckBox12.Checked;
PicSettings.UsaOrarioTestoApplicare = CheckBox8.Checked;
PicSettings.UsaTempoGaraTestoApplicare = CheckBox7.Checked;
PicSettings.UsaRotazioneAutomatica = chkRotazioneAutomatica.Checked;
PicSettings.UsaForzaJpg = chkForzaJpg.Checked;
if (CheckBox17.Checked)
{
PicSettings.TestoNome = true;
}
else
{
PicSettings.TestoNome = false;
}
if (CheckBox16.Checked)
{
PicSettings.NomeData = true;
}
else
{
PicSettings.NomeData = false;
}
PicSettings.TestoFirmaStart = TextBox4.Text;
PicSettings.TestoFirmaStartV = TextBox29.Text;
PicSettings.DataPartenza = DateTimePicker1.Value;
PicSettings.TestoOrario = TextBox18.Text;
PicSettings.AltezzaSmall = Convert.ToInt32(TextBox6.Text);
PicSettings.LarghezzaSmall = Convert.ToInt32(TextBox5.Text);
PicSettings.CreaMiniature = CheckBox1.Checked;
PicSettings.AggiungiScritteMiniature = RadioButton3.Checked;
PicSettings.AggTempoGaraMin = RadioButton5.Checked;
PicSettings.AggNumTempMin = RadioButton7.Checked;
PicSettings.dimVert = Convert.ToInt32(TextBox30.Text);
PicSettings.margVert = Convert.ToInt32(TextBox31.Text);
//PicSettings.NomeFileChild = childFile.Name
PicSettings.Suffisso = TextBox3.Text;
//PicSettings.Codice = TextBox13.Text
PicSettings.Trasparenza = Convert.ToInt32(TextBox9.Text);
PicSettings.IlFont = ComboBox3.SelectedItem.ToString();
PicSettings.Grassetto = CheckBox3.Checked;
PicSettings.Posizione = ComboBox1.SelectedItem.ToString();
PicSettings.Allineamento = ComboBox2.SelectedItem.ToString();
PicSettings.Margine = Convert.ToInt32(TextBox12.Text);
PicSettings.LogoAltezza = Convert.ToInt32(TextBox14.Text);
PicSettings.LogoLarghezza = Convert.ToInt32(TextBox15.Text);
PicSettings.fontColoreRGB = ColorTranslator.FromHtml(TextBox34.Text);
PicSettings.LogoAggiungi = CheckBox5.Checked;
PicSettings.LogoNomeFile = TextBox10.Text;
PicSettings.LogoTrasparenza = TextBox19.Text;
PicSettings.LogoMargine = TextBox16.Text;
PicSettings.LogoPosizioneH = ComboBox4.Text;
PicSettings.LogoPosizioneV = ComboBox5.Text;
PicSettings.FotoGrandeDimOrigina = CheckBox15.Checked;
PicSettings.AltezzaBig = Convert.ToInt32(TextBox27.Text);
PicSettings.LarghezzaBig = Convert.ToInt32(TextBox28.Text);
PicSettings.DimMin = Convert.ToInt32(TextBox25.Text);
PicSettings.TestoMin = RadioButton6.Checked;
PicSettings.jpegQuality = Convert.ToInt64(TextBox32.Text);
PicSettings.jpegQualityMin = Convert.ToInt64(TextBox33.Text);
PicSettings.mainForm = this;
}
private void makeSettingsFromFile()
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Setup (*.xml)|*.xml|All valid files (*.*)|*.*";
openFileDialog.FilterIndex = 0;
openFileDialog.RestoreDirectory = true;
Dictionary<string, object> settingsDict = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
if (DialogResult.OK == openFileDialog.ShowDialog())
{
XMLSettings xmlSettings = new XMLSettings(openFileDialog.FileName);
settingsDict = xmlSettings.getParametriDict();
settingsDict = bindSettings(settingsDict);
setLogoMiniature();
this.Text = string.Format("Image Catalog - {0}", openFileDialog.FileName);
}
}
private void setLogoMiniature()
{
if (File.Exists(TextBox10.Text))
{
PictureBox1.Image = Image.FromFile(TextBox10.Text);
if (PictureBox1.Image.Height >= PictureBox1.Image.Width)
{
PictureBox1.Height = 160;
PictureBox1.Width = Convert.ToInt32(160 * PictureBox1.Image.Width / PictureBox1.Image.Height);
}
else
{
PictureBox1.Width = 224;
PictureBox1.Height = Convert.ToInt32(224 * PictureBox1.Image.Height / PictureBox1.Image.Width);
}
}
}
private Dictionary<string, object> bindSettings(Dictionary<string, object> dict)
{
txtSorgente.Text = dict["dirSorgente"].ToString();
txtDestinazione.Text = dict["dirDestinazione"].ToString();
chkAggiornaSottodirectory.Checked = Convert.ToBoolean(dict["DirSottoDirectory"]);
chkCreaSottocartelle.Checked = Convert.ToBoolean(dict["dirDividiDestinazione"]);
txtFilePerCartella.Text = dict["dirDividiNumFile"].ToString();
txtSuffissoCartelle.Text = dict["dirDividiSuffisso"].ToString();
txtCifreContatore.Text = dict["dirDividiNumCifre"].ToString();
if (dict["dirDividiTipoNumerazione"].ToString().ToUpper() == "PROGRESSIVA")
rdbNumProgressiva.Checked = true;
else
rdbNumFiles.Checked = true;
CheckBox1.Checked = Convert.ToBoolean(dict["miniatureCrea"]);
TextBox3.Text = dict["miniatureSuffisso"].ToString();
TextBox5.Text = dict["miniatureAltezza"].ToString();
TextBox6.Text = dict["miniatureLarghezza"].ToString();
RadioButton3.Checked = Convert.ToBoolean(dict["miniatureAddScritta"]);
RadioButton4.Checked = Convert.ToBoolean(dict["miniatureAddOrario"]);
TextBox27.Text = dict["fotoAltezza"].ToString();
TextBox28.Text = dict["fotoLarghezza"].ToString();
TextBox11.Text = dict["fontDimensione"].ToString();
TextBox25.Text = dict["fontDimensioneMiniatura"].ToString();
CheckBox3.Checked = Convert.ToBoolean(dict["fontBold"]);
ComboBox3.Text = dict["fontNome"].ToString();
TextBox4.Text = dict["testoTesto"].ToString();
TextBox9.Text = dict["testoTrasparente"].ToString();
TextBox12.Text = dict["testoMargine"].ToString();
ComboBox1.Text = dict["testoPosizione"].ToString();
ComboBox2.Text = dict["testoAllineamento"].ToString();
TextBox10.Text = dict["marchioFile"].ToString();
TextBox14.Text = dict["marchioAltezza"].ToString();
TextBox15.Text = dict["marchioLarghezza"].ToString();
TextBox16.Text = dict["marchioMargine"].ToString();
ComboBox4.Text = dict["marchioAllOrizzontale"].ToString();
ComboBox5.Text = dict["marchioAllVerticale"].ToString();
TextBox19.Text = dict["marchioTrasparenza"].ToString();
CheckBox5.Checked = Convert.ToBoolean(dict["MarchioAggiungi"]);
CheckBox7.Checked = Convert.ToBoolean(dict["tempoGara"]);
CheckBox8.Checked = Convert.ToBoolean(dict["orario"]);
TextBox18.Text = dict["etichettaOrario"].ToString();
chkForzaJpg.Checked = Convert.ToBoolean(dict["generaleForzaJpg"]);
chkRotazioneAutomatica.Checked = Convert.ToBoolean(dict["generaleRotazioneAutomatica"]);
TextBox30.Text = dict["grandezzaVerticale"].ToString();
TextBox31.Text = dict["margineVerticale"].ToString();
CheckBox15.Checked = Convert.ToBoolean(dict["dimensioniOriginali"]);
TextBox29.Text = dict["testoVerticale"].ToString();
RadioButton6.Checked = Convert.ToBoolean(dict["nomeMiniatura"]);
CheckBox16.Checked = Convert.ToBoolean(dict["dataFoto"]);
CheckBox17.Checked = Convert.ToBoolean(dict["numeroFoto"]);
RadioButton5.Checked = Convert.ToBoolean(dict["tempoSmall"]);
RadioButton7.Checked = Convert.ToBoolean(dict["numTempoSmall"]);
TextBox32.Text = dict["compressioneJpeg"].ToString();
TextBox33.Text = dict["compressioneJpegMiniatura"].ToString();
TextBox34.Text = dict["coloreTestoRGB"].ToString();
return dict;
}
private void caricaImpostazioniToolStripMenuItem_Click(object sender, EventArgs e)
{
makeSettingsFromFile();
}
private void btnStopCreazione_Click(object sender, EventArgs e)
{
}
private void informazioniToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutForm about = new AboutForm();
about.Show();
}
private void CheckBox2_CheckedChanged(object sender, EventArgs e)
{
if (CheckBox2.Checked)
panelTesto.Enabled = true;
else
panelTesto.Enabled = false;
}
private void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
if (CheckBox1.Checked)
panelMiniature.Enabled = true;
else
panelMiniature.Enabled = false;
}
}
}

View file

@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -1,92 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ImageCatalogCS
{
static class PicSettings
{
// Root
public static string directorySorgente { get; set; }
public static string directoryDestinazione { get; set; }
public static int dimVert { get; set; }
public static int margVert { get; set; }
public static int dimStandard { get; set; }
public static int dimStandardMiniatura { get; set; }
public static bool NomeData { get; set; }
public static bool TestoNome { get; set; }
public static bool UsaOrarioMiniatura { get; set; }
public static bool UsaOrarioTestoApplicare { get; set; }
public static bool UsaTempoGaraTestoApplicare { get; set; }
public static string TestoFirmaStart { get; set; }
public static string TestoFirmaStartV { get; set; }
public static DateTime DataPartenza { get; set; }
public static string TestoOrario { get; set; }
public static bool UsaRotazioneAutomatica { get; set; }
public static bool UsaForzaJpg { get; set; }
public static int LarghezzaSmall { get; set; }
public static int AltezzaSmall { get; set; }
public static bool CreaMiniature { get; set; }
public static bool AggiungiScritteMiniature { get; set; }
public static bool AggTempoGaraMin { get; set; }
public static bool AggNumTempMin { get; set; }
public static string Suffisso { get; set; }
public static string Codice { get; set; }
public static int Trasparenza { get; set; }
public static string IlFont { get; set; }
public static bool Grassetto { get; set; }
public static string Posizione { get; set; }
public static string Allineamento { get; set; }
public static int Margine { get; set; }
public static int LogoAltezza { get; set; }
public static int LogoLarghezza { get; set; }
public static Color fontColoreRGB { get; set; }
public static bool LogoAggiungi { get; set; }
public static string LogoNomeFile { get; set; }
public static string LogoTrasparenza { get; set; }
public static string LogoMargine { get; set; }
public static string LogoPosizioneH { get; set; }
public static string LogoPosizioneV { get; set; }
public static bool FotoGrandeDimOrigina { get; set; }
public static int AltezzaBig { get; set; }
public static int LarghezzaBig { get; set; }
public static DirectoryInfo DestDir { get; set; }
public static int DimMin { get; set; }
public static bool TestoMin { get; set; }
public static bool SecretDefault { get; set; }
public static bool SecretBig { get; set; }
public static bool SecretSmall { get; set; }
public static string SecretPathSmall { get; set; }
public static string SecretPathBig { get; set; }
public static long jpegQuality { get; set; }
public static long jpegQualityMin { get; set; }
public static bool FotoRuotaADestra { get; set; } // Default False
public static bool FotoRuotaASinistra { get; set; } // Default False
public static string TempMinText { get; set; } // Default ""
public static MainForm mainForm { get; set; }
}
}

View file

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ImageCatalogCS
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}

View file

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ImageCatalogCS")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ImageCatalogCS")]
[assembly: AssemblyCopyright("Copyright © 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("00b0a7a5-0de0-48e6-b0c9-ec214aa338dd")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ImageCatalogCS.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ImageCatalogCS.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View file

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -1,26 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ImageCatalogCS.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.11.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View file

@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View file

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
namespace ImageCatalogCS
{
public class Temperature
{
public double CurrentValue { get; set; }
public string InstanceName { get; set; }
public static List<Temperature> Temperatures
{
get
{
List<Temperature> result = new List<Temperature>();
ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"root\WMI", "SELECT * FROM MSAcpi_ThermalZoneTemperature");
foreach (ManagementObject obj in searcher.Get())
{
Double temp = Convert.ToDouble(obj["CurrentTemperature"].ToString());
temp = (temp - 2732) / 10.0;
result.Add(new Temperature { CurrentValue = temp, InstanceName = obj["InstanceName"].ToString() });
}
return result;
}
}
}
}

View file

@ -1,208 +0,0 @@
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
public class XMLSettings
{
private DataSet _ElencoParametri;
private string _NomeFileSetup;
public XMLSettings(string FileSetup)
{
_ElencoParametri = new DataSet();
_NomeFileSetup = FileSetup;
if (!string.IsNullOrEmpty(FileSetup))
{
CaricaParametriSetup();
}
}
public XMLSettings()
{
_ElencoParametri = new DataSet();
_NomeFileSetup = "";
}
public void CaricaParametriSetup()
{
_ElencoParametri = LeggiXmlDataSet("Setup", _NomeFileSetup, "Nome");
}
public void SalvaParametriSetup()
{
if (System.IO.File.Exists(_NomeFileSetup) == true)
{
File.Delete(_NomeFileSetup);
}
_ElencoParametri.WriteXml(_NomeFileSetup);
}
public Dictionary<string, object> getParametriDict()
{
CaricaParametriSetup();
Dictionary<string, object> dictParam = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
//DataRow[] LElenco = _ElencoParametri.Tables["Setup"].Select("Nome='" + NomeParametro + "'");
//DataTable table = _ElencoParametri.Tables["Setup"];
foreach (DataRow row in _ElencoParametri.Tables["Setup"].Rows)
{
dictParam.Add(row["Nome"].ToString(), row["Valore"]);
}
return dictParam;
}
public string LeggiParametroString(string NomeParametro)
{
string Risposta = "";
try
{
DataRow[] LElenco = _ElencoParametri.Tables["Setup"].Select("Nome='" + NomeParametro + "'");
DataRow LaRiga = null;
foreach (DataRow LaRiga_loopVariable in LElenco)
{
LaRiga = LaRiga_loopVariable;
Risposta = LaRiga["Valore"].ToString();
}
}
catch
{
Risposta = "";
}
return Risposta;
}
public bool LeggiParametroBoolean(string NomeParametro)
{
string Risposta = "";
try
{
DataRow[] LElenco = _ElencoParametri.Tables["Setup"].Select("Nome='" + NomeParametro + "'");
DataRow LaRiga = null;
foreach (DataRow LaRiga_loopVariable in LElenco)
{
LaRiga = LaRiga_loopVariable;
Risposta = LaRiga["Valore"].ToString();
}
}
catch
{
Risposta = "";
}
switch (Risposta.ToUpper())
{
case "TRUE":
case "OK":
case "SI":
case "1":
case "YES":
case "VERO":
return true;
default:
return false;
}
}
public void AggiornaParametro(string NomeParametro, object ValoreParametro)
{
try
{
if (_ElencoParametri.Tables["Setup"] == null)
{
DataTable TabellaTmp = new DataTable("Setup");
DataRow RigaTmp = null;
DataColumn LaColonna = null;
LaColonna = TabellaTmp.Columns.Add("Nome", System.Type.GetType("System.String"));
LaColonna = TabellaTmp.Columns.Add("Valore", System.Type.GetType("System.String"));
//* Aggiunge alla tabella tutte le righe
RigaTmp = TabellaTmp.NewRow();
RigaTmp["Nome"] = NomeParametro;
RigaTmp["Valore"] = ValoreParametro;
TabellaTmp.Rows.Add(RigaTmp);
_ElencoParametri.Tables.Add(TabellaTmp);
}
else
{
DataRow[] LElenco = _ElencoParametri.Tables["Setup"].Select("Nome='" + NomeParametro + "'");
if (LElenco.Length == 0)
{
DataRow LaRiga = null;
LaRiga = _ElencoParametri.Tables["Setup"].NewRow();
LaRiga["Nome"] = NomeParametro;
LaRiga["Valore"] = ValoreParametro;
_ElencoParametri.Tables["Setup"].Rows.Add(LaRiga);
}
else
{
LElenco[0]["Valore"] = ValoreParametro;
}
}
}
catch
{
}
}
private DataTable LeggiXmlDataTable(string NomeTabella, string NomeFileXml, string NomeColonnaChiave = "")
{
//* Crea e Legge il dataset dal file xml
System.Data.DataSet DataSetXml = new System.Data.DataSet();
DataSetXml.ReadXml(NomeFileXml);
//* Aggiunge il campo chiave
if (!string.IsNullOrEmpty(NomeColonnaChiave))
{
DataSetXml.Tables[NomeTabella].Constraints.Add(NomeColonnaChiave, DataSetXml.Tables[NomeTabella].Columns[NomeColonnaChiave], true);
}
//* Restituisce la risposta
return DataSetXml.Tables[NomeTabella];
}
private static DataSet LeggiXmlDataSet(string NomeTabella, string NomeFileXml, string NomeColonnaChiave = "")
{
//* Crea e Legge il dataset dal file xml
DataSet DataSetXml = new DataSet();
DataSetXml.ReadXml(NomeFileXml);
//* Aggiunge il campo chiave
if (!string.IsNullOrEmpty(NomeColonnaChiave))
{
DataSetXml.Tables[NomeTabella].Constraints.Add(NomeColonnaChiave, DataSetXml.Tables[NomeTabella].Columns[NomeColonnaChiave], true);
}
//* Restituisce la risposta
return DataSetXml;
}
public string NomeFileSetup
{
get { return _NomeFileSetup; }
set { _NomeFileSetup = value; }
}
}

View file

@ -1,251 +0,0 @@
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Threading;
public delegate void ThreadErrorHandlerDelegate(ThreadPoolWorkItem oWorkItem, Exception oError);
public class ThreadPoolWorkItem
{
public bool m_bStoreOutput = false;
public string m_sName = "";
public Delegate m_pMethod = null;
public object[] m_pInput = null;
public object m_oOutput = null;
public Exception m_oException = null;
public ThreadPoolWorkItem()
{
}
public ThreadPoolWorkItem(string sName, Delegate pMethod, object[] pInput, bool bStoreOutput)
{
m_sName = sName;
m_pMethod = pMethod;
m_pInput = pInput;
m_bStoreOutput = bStoreOutput;
}
}
public class XYThreadPool
{
private Hashtable m_htThreads = new Hashtable(256);
private int m_nMinThreadCount = 5;
private int m_nMaxThreadCount = 10;
private int m_nShutdownPause = 200;
private int m_nServerPause = 25;
private bool m_bContinue = false;
private static Exception m_oException = null;
private Queue m_qInput = new Queue(1024);
private Queue m_qOutput = new Queue(1024);
private Delegate m_delegateThreadErrorHandler = new ThreadErrorHandlerDelegate(OnThreadError);
private void ThreadProc()
{
while (m_bContinue)
{
object obj = null;
Monitor.Enter(this);
if (m_qInput.Count > 0)
obj = m_qInput.Dequeue();
Monitor.Exit(this);
if (obj == null)
{
bool bQuit = false;
Monitor.Enter(this);
if (m_htThreads.Count > m_nMinThreadCount)
{
m_htThreads.Remove(Thread.CurrentThread.Name);
bQuit = true;
}
Monitor.Exit(this);
if (bQuit)
return;
Thread.Sleep(10 * m_nServerPause);
}
else
{
ThreadPoolWorkItem oWorkItem = (ThreadPoolWorkItem)obj;
//oWorkItem.m_oOutput = oWorkItem.m_pMethod.DynamicInvoke(oWorkItem.m_pInput)
try
{
oWorkItem.m_oOutput = oWorkItem.m_pMethod.DynamicInvoke(oWorkItem.m_pInput);
}
catch (Exception oBug)
{
if ((m_delegateThreadErrorHandler != null))
{
try
{
object[] pInput = {
oWorkItem,
oBug
};
m_delegateThreadErrorHandler.DynamicInvoke(pInput);
}
catch
{
}
}
}
if (oWorkItem.m_bStoreOutput)
{
Monitor.Enter(m_qOutput);
m_qOutput.Enqueue(oWorkItem);
Monitor.Exit(m_qOutput);
}
Thread.Sleep(m_nServerPause);
}
}
}
private static void OnThreadError(ThreadPoolWorkItem oWorkItem, Exception oError)
{
if (oWorkItem == null)
{
m_oException = oError;
}
else
{
oWorkItem.m_oException = oError;
}
}
public void SetThreadErrorHandler(ThreadErrorHandlerDelegate pMethod)
{
Monitor.Enter(this);
m_delegateThreadErrorHandler = pMethod;
Monitor.Exit(this);
}
public void SetServerPause(int nMilliseconds)
{
Monitor.Enter(this);
if (nMilliseconds > 9 & nMilliseconds < 101)
m_nServerPause = nMilliseconds;
Monitor.Exit(this);
}
public void SetShutdownPause(int nMilliseconds)
{
Monitor.Enter(this);
m_nShutdownPause = nMilliseconds;
Monitor.Exit(this);
}
public Exception GetException()
{
return m_oException;
}
public void InsertWorkItem(ThreadPoolWorkItem oWorkItem)
{
try
{
Monitor.Enter(this);
m_qInput.Enqueue(oWorkItem);
if (m_bContinue && m_qInput.Count > m_htThreads.Count && m_htThreads.Count < m_nMaxThreadCount)
{
Thread th = new Thread(ThreadProc);
th.Name = Guid.NewGuid().ToString();
m_htThreads.Add(th.Name, th);
th.Start();
}
}
catch (Exception oBug)
{
m_oException = oBug;
}
finally
{
Monitor.Exit(this);
}
}
public void InsertWorkItem(string sName, Delegate pMethod, object[] pArgs, bool bStoreOutput)
{
InsertWorkItem(new ThreadPoolWorkItem(sName, pMethod, pArgs, bStoreOutput));
}
public ThreadPoolWorkItem ExtractWorkItem()
{
object oWorkItem = null;
Monitor.Enter(m_qOutput);
if (m_qOutput.Count > 0)
oWorkItem = m_qOutput.Dequeue();
Monitor.Exit(m_qOutput);
if (oWorkItem == null)
return null;
return (ThreadPoolWorkItem)oWorkItem;
}
public bool StartThreadPool(int nMinThreadCount = 5, int nMaxThreadCount = 10)
{
try
{
Monitor.Enter(this);
if (m_bContinue == false)
{
m_bContinue = true;
if (nMinThreadCount > 0)
{
m_nMinThreadCount = nMinThreadCount;
}
if (nMaxThreadCount > m_nMinThreadCount)
{
m_nMaxThreadCount = nMaxThreadCount;
}
else
{
m_nMaxThreadCount = 2 * m_nMinThreadCount;
}
int i = 0;
for (i = 1; i <= m_nMinThreadCount; i++)
{
Thread th = new Thread(ThreadProc);
th.Name = Guid.NewGuid().ToString();
m_htThreads.Add(th.Name, th);
th.Start();
}
}
return true;
}
catch (Exception oBug)
{
m_bContinue = false;
m_oException = oBug;
return false;
}
finally
{
Monitor.Exit(this);
}
}
public void StopThreadPool()
{
Monitor.Enter(this);
m_bContinue = false;
Thread.Sleep(Math.Max(200, m_nShutdownPause));
if ((m_nShutdownPause > 0))
{
IDictionaryEnumerator dict = m_htThreads.GetEnumerator();
while (dict.MoveNext())
{
Thread th = (Thread)dict.Value;
if (th.IsAlive)
{
try
{
th.Abort();
}
catch
{
}
}
}
}
m_htThreads.Clear();
m_qInput.Clear();
// m_qOutput.Clear()
Monitor.Exit(this);
}
public int GetThreadCount()
{
Monitor.Enter(this);
int nCount = m_htThreads.Count;
Monitor.Exit(this);
return nCount;
}
}

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>

File diff suppressed because it is too large Load diff

View file

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ImageCatalogParallel
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View file

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -1,83 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{0F42DA5C-2788-48BD-BACA-01625C3CFFBB}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>ImageCatalogParallel</RootNamespace>
<AssemblyName>ImageCatalogParallel</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ImageCatalogParallel
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

Some files were not shown because too many files have changed in this diff Show more