claude-mpm 4.17.0__py3-none-any.whl → 4.18.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +48 -17
- claude_mpm/agents/agent_loader.py +4 -4
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/services/agents/auto_config_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/local_template_manager.py +1 -1
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/mcp_config_manager.py +2 -2
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/unified/deployment_strategies/local.py +1 -1
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +567 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/utils/agent_dependency_loader.py +2 -2
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/METADATA +68 -1
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/RECORD +47 -24
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/WHEEL +0 -0
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill_id: git-workflow
|
|
3
|
+
skill_version: 0.1.0
|
|
4
|
+
description: Essential Git patterns for effective version control, eliminating redundant Git guidance per agent.
|
|
5
|
+
updated_at: 2025-10-30T17:00:00Z
|
|
6
|
+
tags: [git, version-control, workflow, best-practices]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Git Workflow
|
|
10
|
+
|
|
11
|
+
Essential Git patterns for effective version control. Eliminates ~120-150 lines of redundant Git guidance per agent.
|
|
12
|
+
|
|
13
|
+
## Commit Best Practices
|
|
14
|
+
|
|
15
|
+
### Conventional Commits Format
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
<type>(<scope>): <subject>
|
|
19
|
+
|
|
20
|
+
<body>
|
|
21
|
+
|
|
22
|
+
<footer>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Types:**
|
|
26
|
+
- `feat`: New feature
|
|
27
|
+
- `fix`: Bug fix
|
|
28
|
+
- `docs`: Documentation only
|
|
29
|
+
- `refactor`: Code change that neither fixes bug nor adds feature
|
|
30
|
+
- `perf`: Performance improvement
|
|
31
|
+
- `test`: Adding or updating tests
|
|
32
|
+
- `chore`: Build process, dependencies, tooling
|
|
33
|
+
|
|
34
|
+
**Examples:**
|
|
35
|
+
```bash
|
|
36
|
+
feat(auth): add OAuth2 authentication
|
|
37
|
+
|
|
38
|
+
Implements OAuth2 flow using Google provider.
|
|
39
|
+
Includes token refresh and validation.
|
|
40
|
+
|
|
41
|
+
Closes #123
|
|
42
|
+
|
|
43
|
+
fix(api): handle null response in user endpoint
|
|
44
|
+
|
|
45
|
+
Previously crashed when user not found.
|
|
46
|
+
Now returns 404 with error message.
|
|
47
|
+
|
|
48
|
+
perf(db): optimize user query with index
|
|
49
|
+
|
|
50
|
+
Reduces query time from 500ms to 50ms.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Atomic Commits
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Good: Each commit does one thing
|
|
57
|
+
git commit -m "feat: add user authentication"
|
|
58
|
+
git commit -m "test: add auth tests"
|
|
59
|
+
git commit -m "docs: update API docs for auth"
|
|
60
|
+
|
|
61
|
+
# Bad: Multiple unrelated changes
|
|
62
|
+
git commit -m "add auth, fix bugs, update docs"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Branching Strategy
|
|
66
|
+
|
|
67
|
+
### Git Flow (Feature Branches)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Create feature branch from main
|
|
71
|
+
git checkout main
|
|
72
|
+
git pull origin main
|
|
73
|
+
git checkout -b feature/user-authentication
|
|
74
|
+
|
|
75
|
+
# Work on feature with regular commits
|
|
76
|
+
git add src/auth.py
|
|
77
|
+
git commit -m "feat(auth): implement login endpoint"
|
|
78
|
+
|
|
79
|
+
# Keep branch updated with main
|
|
80
|
+
git checkout main
|
|
81
|
+
git pull origin main
|
|
82
|
+
git checkout feature/user-authentication
|
|
83
|
+
git rebase main # Or: git merge main
|
|
84
|
+
|
|
85
|
+
# Push and create PR
|
|
86
|
+
git push -u origin feature/user-authentication
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Trunk-Based Development
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Work directly on main with short-lived branches
|
|
93
|
+
git checkout main
|
|
94
|
+
git pull origin main
|
|
95
|
+
git checkout -b fix/null-pointer
|
|
96
|
+
# Make small change
|
|
97
|
+
git commit -m "fix: handle null in user query"
|
|
98
|
+
git push origin fix/null-pointer
|
|
99
|
+
# Merge immediately via PR
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Common Workflows
|
|
103
|
+
|
|
104
|
+
### Updating Branch with Latest Changes
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Option 1: Rebase (cleaner history)
|
|
108
|
+
git checkout feature-branch
|
|
109
|
+
git fetch origin
|
|
110
|
+
git rebase origin/main
|
|
111
|
+
|
|
112
|
+
# Resolve conflicts if any
|
|
113
|
+
git add resolved_file.py
|
|
114
|
+
git rebase --continue
|
|
115
|
+
|
|
116
|
+
# Option 2: Merge (preserves history)
|
|
117
|
+
git checkout feature-branch
|
|
118
|
+
git merge origin/main
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Undoing Changes
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Undo last commit (keep changes)
|
|
125
|
+
git reset --soft HEAD~1
|
|
126
|
+
|
|
127
|
+
# Undo last commit (discard changes)
|
|
128
|
+
git reset --hard HEAD~1
|
|
129
|
+
|
|
130
|
+
# Undo changes to specific file
|
|
131
|
+
git checkout -- file.py
|
|
132
|
+
|
|
133
|
+
# Revert a commit (creates new commit)
|
|
134
|
+
git revert abc123
|
|
135
|
+
|
|
136
|
+
# Amend last commit
|
|
137
|
+
git add forgotten_file.py
|
|
138
|
+
git commit --amend --no-edit
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Stashing Work
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Save current work temporarily
|
|
145
|
+
git stash
|
|
146
|
+
|
|
147
|
+
# List stashes
|
|
148
|
+
git stash list
|
|
149
|
+
|
|
150
|
+
# Apply most recent stash
|
|
151
|
+
git stash pop
|
|
152
|
+
|
|
153
|
+
# Apply specific stash
|
|
154
|
+
git stash apply stash@{0}
|
|
155
|
+
|
|
156
|
+
# Create named stash
|
|
157
|
+
git stash save "WIP: authentication feature"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Cherry-Picking Commits
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Apply specific commit from another branch
|
|
164
|
+
git cherry-pick abc123
|
|
165
|
+
|
|
166
|
+
# Cherry-pick multiple commits
|
|
167
|
+
git cherry-pick abc123 def456
|
|
168
|
+
|
|
169
|
+
# Cherry-pick without committing
|
|
170
|
+
git cherry-pick -n abc123
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Resolving Conflicts
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# When conflicts occur during merge/rebase
|
|
177
|
+
# 1. Check conflicted files
|
|
178
|
+
git status
|
|
179
|
+
|
|
180
|
+
# 2. Edit files to resolve conflicts
|
|
181
|
+
# Look for conflict markers:
|
|
182
|
+
<<<<<<< HEAD
|
|
183
|
+
Your changes
|
|
184
|
+
=======
|
|
185
|
+
Their changes
|
|
186
|
+
>>>>>>> branch-name
|
|
187
|
+
|
|
188
|
+
# 3. Mark as resolved
|
|
189
|
+
git add resolved_file.py
|
|
190
|
+
|
|
191
|
+
# 4. Continue operation
|
|
192
|
+
git rebase --continue # or git merge --continue
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Viewing History
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# Compact log
|
|
199
|
+
git log --oneline -10
|
|
200
|
+
|
|
201
|
+
# Graphical log
|
|
202
|
+
git log --graph --oneline --all
|
|
203
|
+
|
|
204
|
+
# Commits by author
|
|
205
|
+
git log --author="John Doe"
|
|
206
|
+
|
|
207
|
+
# Commits affecting specific file
|
|
208
|
+
git log -- path/to/file.py
|
|
209
|
+
|
|
210
|
+
# See changes in commit
|
|
211
|
+
git show abc123
|
|
212
|
+
|
|
213
|
+
# Compare branches
|
|
214
|
+
git diff main..feature-branch
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Branch Management
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# List branches
|
|
221
|
+
git branch -a # All branches (local + remote)
|
|
222
|
+
|
|
223
|
+
# Delete local branch
|
|
224
|
+
git branch -d feature-branch # Safe delete (merged only)
|
|
225
|
+
git branch -D feature-branch # Force delete
|
|
226
|
+
|
|
227
|
+
# Delete remote branch
|
|
228
|
+
git push origin --delete feature-branch
|
|
229
|
+
|
|
230
|
+
# Rename branch
|
|
231
|
+
git branch -m old-name new-name
|
|
232
|
+
|
|
233
|
+
# Track remote branch
|
|
234
|
+
git checkout --track origin/feature-branch
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Tags
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
# Create lightweight tag
|
|
241
|
+
git tag v1.0.0
|
|
242
|
+
|
|
243
|
+
# Create annotated tag (recommended)
|
|
244
|
+
git tag -a v1.0.0 -m "Release version 1.0.0"
|
|
245
|
+
|
|
246
|
+
# Push tags to remote
|
|
247
|
+
git push origin v1.0.0
|
|
248
|
+
git push origin --tags # Push all tags
|
|
249
|
+
|
|
250
|
+
# Checkout tag
|
|
251
|
+
git checkout v1.0.0
|
|
252
|
+
|
|
253
|
+
# Delete tag
|
|
254
|
+
git tag -d v1.0.0
|
|
255
|
+
git push origin --delete v1.0.0
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Advanced Operations
|
|
259
|
+
|
|
260
|
+
### Interactive Rebase
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Edit last 3 commits
|
|
264
|
+
git rebase -i HEAD~3
|
|
265
|
+
|
|
266
|
+
# Options in editor:
|
|
267
|
+
# pick = use commit
|
|
268
|
+
# reword = change commit message
|
|
269
|
+
# edit = stop to amend commit
|
|
270
|
+
# squash = combine with previous commit
|
|
271
|
+
# fixup = like squash but discard message
|
|
272
|
+
# drop = remove commit
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Bisect (Find Bug Introduction)
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
# Start bisect
|
|
279
|
+
git bisect start
|
|
280
|
+
git bisect bad # Current version has bug
|
|
281
|
+
git bisect good v1.0.0 # This version was good
|
|
282
|
+
|
|
283
|
+
# Git checks out middle commit
|
|
284
|
+
# Test if bug exists
|
|
285
|
+
git bisect bad # if bug exists
|
|
286
|
+
git bisect good # if bug doesn't exist
|
|
287
|
+
|
|
288
|
+
# Git narrows down until finding first bad commit
|
|
289
|
+
git bisect reset # Return to original branch
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Blame (Find Who Changed Line)
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
# See who last modified each line
|
|
296
|
+
git blame file.py
|
|
297
|
+
|
|
298
|
+
# Ignore whitespace changes
|
|
299
|
+
git blame -w file.py
|
|
300
|
+
|
|
301
|
+
# Show specific line range
|
|
302
|
+
git blame -L 10,20 file.py
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Git Hooks
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# Pre-commit hook (runs before commit)
|
|
309
|
+
# .git/hooks/pre-commit
|
|
310
|
+
#!/bin/bash
|
|
311
|
+
npm run lint
|
|
312
|
+
npm test
|
|
313
|
+
|
|
314
|
+
# Pre-push hook (runs before push)
|
|
315
|
+
# .git/hooks/pre-push
|
|
316
|
+
#!/bin/bash
|
|
317
|
+
npm run test:integration
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Best Practices
|
|
321
|
+
|
|
322
|
+
### ✅ DO
|
|
323
|
+
|
|
324
|
+
- Commit frequently with atomic changes
|
|
325
|
+
- Write clear, descriptive commit messages
|
|
326
|
+
- Pull before push to avoid conflicts
|
|
327
|
+
- Review changes before committing (`git diff --staged`)
|
|
328
|
+
- Use branches for features and fixes
|
|
329
|
+
- Keep commits small and focused
|
|
330
|
+
|
|
331
|
+
### ❌ DON'T
|
|
332
|
+
|
|
333
|
+
- Commit sensitive data (use `.gitignore`)
|
|
334
|
+
- Commit generated files (build artifacts, `node_modules`)
|
|
335
|
+
- Force push to shared branches (`git push --force`)
|
|
336
|
+
- Commit work-in-progress to main
|
|
337
|
+
- Include multiple unrelated changes in one commit
|
|
338
|
+
- Rewrite public history
|
|
339
|
+
|
|
340
|
+
## .gitignore Patterns
|
|
341
|
+
|
|
342
|
+
```gitignore
|
|
343
|
+
# Dependencies
|
|
344
|
+
node_modules/
|
|
345
|
+
venv/
|
|
346
|
+
__pycache__/
|
|
347
|
+
|
|
348
|
+
# Build outputs
|
|
349
|
+
dist/
|
|
350
|
+
build/
|
|
351
|
+
*.pyc
|
|
352
|
+
*.o
|
|
353
|
+
*.exe
|
|
354
|
+
|
|
355
|
+
# IDE
|
|
356
|
+
.vscode/
|
|
357
|
+
.idea/
|
|
358
|
+
*.swp
|
|
359
|
+
|
|
360
|
+
# Secrets
|
|
361
|
+
.env
|
|
362
|
+
*.key
|
|
363
|
+
*.pem
|
|
364
|
+
secrets.yml
|
|
365
|
+
|
|
366
|
+
# OS
|
|
367
|
+
.DS_Store
|
|
368
|
+
Thumbs.db
|
|
369
|
+
|
|
370
|
+
# Logs
|
|
371
|
+
*.log
|
|
372
|
+
logs/
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Quick Command Reference
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
# Status and diff
|
|
379
|
+
git status
|
|
380
|
+
git diff
|
|
381
|
+
git diff --staged
|
|
382
|
+
|
|
383
|
+
# Commit
|
|
384
|
+
git add .
|
|
385
|
+
git commit -m "message"
|
|
386
|
+
git push
|
|
387
|
+
|
|
388
|
+
# Branch
|
|
389
|
+
git branch
|
|
390
|
+
git checkout -b branch-name
|
|
391
|
+
git merge branch-name
|
|
392
|
+
|
|
393
|
+
# Update
|
|
394
|
+
git pull
|
|
395
|
+
git fetch
|
|
396
|
+
|
|
397
|
+
# Undo
|
|
398
|
+
git reset HEAD~1
|
|
399
|
+
git checkout -- file
|
|
400
|
+
git revert commit-hash
|
|
401
|
+
|
|
402
|
+
# History
|
|
403
|
+
git log
|
|
404
|
+
git log --oneline
|
|
405
|
+
git show commit-hash
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## Remember
|
|
409
|
+
|
|
410
|
+
- **Commit often** - Small commits are easier to review and revert
|
|
411
|
+
- **Descriptive messages** - Future you will thank present you
|
|
412
|
+
- **Pull before push** - Stay synchronized with team
|
|
413
|
+
- **Use branches** - Keep main stable
|
|
414
|
+
- **Review before commit** - Check what you're committing
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill_id: imagemagick
|
|
3
|
+
skill_version: 0.1.0
|
|
4
|
+
description: Image manipulation and optimization techniques using ImageMagick.
|
|
5
|
+
updated_at: 2025-10-30T17:00:00Z
|
|
6
|
+
tags: [imagemagick, image-processing, optimization, media]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# ImageMagick/Image Optimization
|
|
10
|
+
|
|
11
|
+
Image manipulation and optimization techniques.
|
|
12
|
+
|
|
13
|
+
## ImageMagick CLI
|
|
14
|
+
|
|
15
|
+
### Basic Operations
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Resize image
|
|
19
|
+
convert input.jpg -resize 800x600 output.jpg
|
|
20
|
+
|
|
21
|
+
# Convert format
|
|
22
|
+
convert input.png output.jpg
|
|
23
|
+
|
|
24
|
+
# Compress JPEG
|
|
25
|
+
convert input.jpg -quality 85 output.jpg
|
|
26
|
+
|
|
27
|
+
# Create thumbnail
|
|
28
|
+
convert input.jpg -thumbnail 200x200 thumb.jpg
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Batch Operations
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Resize all images in directory
|
|
35
|
+
for img in *.jpg; do
|
|
36
|
+
convert "$img" -resize 800x600 "resized_$img"
|
|
37
|
+
done
|
|
38
|
+
|
|
39
|
+
# Convert all PNGs to JPGs
|
|
40
|
+
mogrify -format jpg *.png
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Advanced
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Add watermark
|
|
47
|
+
convert input.jpg watermark.png -gravity southeast -composite output.jpg
|
|
48
|
+
|
|
49
|
+
# Crop image
|
|
50
|
+
convert input.jpg -crop 800x600+100+100 output.jpg
|
|
51
|
+
|
|
52
|
+
# Rotate
|
|
53
|
+
convert input.jpg -rotate 90 output.jpg
|
|
54
|
+
|
|
55
|
+
# Grayscale
|
|
56
|
+
convert input.jpg -colorspace Gray output.jpg
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Python (Pillow)
|
|
60
|
+
|
|
61
|
+
### Basic Operations
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from PIL import Image
|
|
65
|
+
|
|
66
|
+
# Open image
|
|
67
|
+
img = Image.open('input.jpg')
|
|
68
|
+
|
|
69
|
+
# Resize
|
|
70
|
+
img_resized = img.resize((800, 600))
|
|
71
|
+
img_resized.save('output.jpg')
|
|
72
|
+
|
|
73
|
+
# Convert format
|
|
74
|
+
img.save('output.png')
|
|
75
|
+
|
|
76
|
+
# Compress
|
|
77
|
+
img.save('compressed.jpg', quality=85, optimize=True)
|
|
78
|
+
|
|
79
|
+
# Thumbnail
|
|
80
|
+
img.thumbnail((200, 200))
|
|
81
|
+
img.save('thumb.jpg')
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Advanced Operations
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
# Crop
|
|
88
|
+
box = (100, 100, 900, 700) # left, top, right, bottom
|
|
89
|
+
cropped = img.crop(box)
|
|
90
|
+
|
|
91
|
+
# Rotate
|
|
92
|
+
rotated = img.rotate(90, expand=True)
|
|
93
|
+
|
|
94
|
+
# Grayscale
|
|
95
|
+
gray = img.convert('L')
|
|
96
|
+
|
|
97
|
+
# Add watermark
|
|
98
|
+
watermark = Image.open('watermark.png')
|
|
99
|
+
img.paste(watermark, (img.width - watermark.width, img.height - watermark.height), watermark)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Optimization
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
# Optimize PNG
|
|
106
|
+
from PIL import Image
|
|
107
|
+
|
|
108
|
+
img = Image.open('input.png')
|
|
109
|
+
img.save('optimized.png', optimize=True)
|
|
110
|
+
|
|
111
|
+
# Optimize JPEG
|
|
112
|
+
img.save('optimized.jpg', quality=85, optimize=True, progressive=True)
|
|
113
|
+
|
|
114
|
+
# WebP format (better compression)
|
|
115
|
+
img.save('output.webp', quality=80)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## JavaScript (sharp)
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
const sharp = require('sharp');
|
|
122
|
+
|
|
123
|
+
// Resize
|
|
124
|
+
await sharp('input.jpg')
|
|
125
|
+
.resize(800, 600)
|
|
126
|
+
.toFile('output.jpg');
|
|
127
|
+
|
|
128
|
+
// Compress
|
|
129
|
+
await sharp('input.jpg')
|
|
130
|
+
.jpeg({ quality: 85 })
|
|
131
|
+
.toFile('compressed.jpg');
|
|
132
|
+
|
|
133
|
+
// Convert format
|
|
134
|
+
await sharp('input.png')
|
|
135
|
+
.jpeg()
|
|
136
|
+
.toFile('output.jpg');
|
|
137
|
+
|
|
138
|
+
// Thumbnail
|
|
139
|
+
await sharp('input.jpg')
|
|
140
|
+
.resize(200, 200, { fit: 'cover' })
|
|
141
|
+
.toFile('thumb.jpg');
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Image Optimization Guidelines
|
|
145
|
+
|
|
146
|
+
### Web Images
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
Format recommendations:
|
|
150
|
+
- Photos: JPEG (quality 85) or WebP (quality 80)
|
|
151
|
+
- Graphics/logos: PNG or SVG
|
|
152
|
+
- Animations: WebP or video
|
|
153
|
+
|
|
154
|
+
Size recommendations:
|
|
155
|
+
- Hero images: 1920px width max
|
|
156
|
+
- Content images: 1200px width max
|
|
157
|
+
- Thumbnails: 200-400px
|
|
158
|
+
- Icons: 64px or SVG
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Responsive Images
|
|
162
|
+
|
|
163
|
+
```html
|
|
164
|
+
<picture>
|
|
165
|
+
<source srcset="image-320w.jpg" media="(max-width: 320px)">
|
|
166
|
+
<source srcset="image-640w.jpg" media="(max-width: 640px)">
|
|
167
|
+
<source srcset="image-1024w.jpg" media="(max-width: 1024px)">
|
|
168
|
+
<img src="image-1920w.jpg" alt="Description">
|
|
169
|
+
</picture>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Common Tasks
|
|
173
|
+
|
|
174
|
+
### Bulk Resize and Compress
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
from PIL import Image
|
|
178
|
+
import os
|
|
179
|
+
|
|
180
|
+
def optimize_images(input_dir, output_dir, max_size=(1200, 1200)):
|
|
181
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
182
|
+
|
|
183
|
+
for filename in os.listdir(input_dir):
|
|
184
|
+
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
|
|
185
|
+
input_path = os.path.join(input_dir, filename)
|
|
186
|
+
output_path = os.path.join(output_dir, filename)
|
|
187
|
+
|
|
188
|
+
img = Image.open(input_path)
|
|
189
|
+
img.thumbnail(max_size, Image.Resampling.LANCZOS)
|
|
190
|
+
|
|
191
|
+
if filename.lower().endswith('.png'):
|
|
192
|
+
img.save(output_path, 'PNG', optimize=True)
|
|
193
|
+
else:
|
|
194
|
+
img.save(output_path, 'JPEG', quality=85, optimize=True)
|
|
195
|
+
|
|
196
|
+
optimize_images('originals/', 'optimized/')
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Remember
|
|
200
|
+
- Always keep original files
|
|
201
|
+
- Test optimized images for quality
|
|
202
|
+
- Use WebP for modern browsers
|
|
203
|
+
- Progressive JPEGs for better perceived load time
|
|
204
|
+
- Lazy load images not in viewport
|