mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-13 16:46:37 +08:00
优化番号海报图片获取逻辑
优化番号海报图片获取逻辑
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
"image/draw"
|
||||
"image/jpeg"
|
||||
_ "image/png" // register PNG decoder
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IsAdultMediaPathOrMetadata reports whether media is adult based on path, mediaType, nsfw flag, or adult code.
|
||||
func IsAdultMediaPathOrMetadata(path, mediaType string, nsfw bool) bool {
|
||||
if nsfw {
|
||||
return true
|
||||
}
|
||||
if normalizeOrganizeMediaType(mediaType) == "adult" {
|
||||
return true
|
||||
}
|
||||
if AdultCodeFromMediaPath(path) != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsAdultArtworkURL reports whether the URL is likely an adult cover/poster image.
|
||||
func IsAdultArtworkURL(raw string) bool {
|
||||
lower := strings.ToLower(raw)
|
||||
return strings.Contains(lower, "javbus") ||
|
||||
strings.Contains(lower, "javdb") ||
|
||||
strings.Contains(lower, "jdbstatic") ||
|
||||
strings.Contains(lower, "busjav") ||
|
||||
strings.Contains(lower, "dmmbus") ||
|
||||
strings.Contains(lower, "cdnbus") ||
|
||||
strings.Contains(lower, "javsee") ||
|
||||
strings.Contains(lower, "/covers/") ||
|
||||
strings.Contains(lower, "pics.dmm.co.jp")
|
||||
}
|
||||
|
||||
// CropAdultCoverPoster checks if the image data is a wide full-jacket DVD cover (width > height * 1.15).
|
||||
// If so, it crops the right portion (the front cover poster) and returns the encoded JPEG bytes.
|
||||
// If the image is already portrait or cannot be decoded, it safely returns the original data.
|
||||
func CropAdultCoverPoster(data []byte) ([]byte, string, error) {
|
||||
if len(data) == 0 {
|
||||
return data, "", nil
|
||||
}
|
||||
src, format, err := image.Decode(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return data, format, err
|
||||
}
|
||||
bounds := src.Bounds()
|
||||
width := bounds.Dx()
|
||||
height := bounds.Dy()
|
||||
if width <= 0 || height <= 0 {
|
||||
return data, format, nil
|
||||
}
|
||||
// If the image is already portrait or square, keep it as-is.
|
||||
if float64(width) <= float64(height)*1.15 {
|
||||
return data, format, nil
|
||||
}
|
||||
|
||||
// Front cover width is typically ~0.70-0.72 of the height (or right ~50-52% of total width)
|
||||
cropWidth := int(float64(height) * 0.71)
|
||||
maxCropWidth := int(float64(width) * 0.53)
|
||||
if cropWidth > maxCropWidth {
|
||||
cropWidth = maxCropWidth
|
||||
}
|
||||
if cropWidth <= 0 {
|
||||
cropWidth = width / 2
|
||||
}
|
||||
minX := bounds.Max.X - cropWidth
|
||||
if minX < bounds.Min.X {
|
||||
minX = bounds.Min.X
|
||||
}
|
||||
|
||||
cropRect := image.Rect(minX, bounds.Min.Y, bounds.Max.X, bounds.Max.Y)
|
||||
type subImager interface {
|
||||
SubImage(r image.Rectangle) image.Image
|
||||
}
|
||||
var cropped image.Image
|
||||
if si, ok := src.(subImager); ok {
|
||||
cropped = si.SubImage(cropRect)
|
||||
} else {
|
||||
dst := image.NewRGBA(image.Rect(0, 0, cropRect.Dx(), cropRect.Dy()))
|
||||
draw.Draw(dst, dst.Bounds(), src, cropRect.Min, draw.Src)
|
||||
cropped = dst
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := jpeg.Encode(&buf, cropped, &jpeg.Options{Quality: 92}); err != nil {
|
||||
return data, format, err
|
||||
}
|
||||
return buf.Bytes(), "image/jpeg", nil
|
||||
}
|
||||
Reference in New Issue
Block a user