2009-12-15 7 views
7

पर पीएनजी छवि के खाली सीमा क्षेत्र को कैसे कट करें और इसे पायथन का उपयोग करके अपने न्यूनतम आकार में कैसे घटाएं?पीएनजी छवि को अपने न्यूनतम आकार

+0

क्या सीमा क्षेत्र का आकार स्थिर है? यदि ऐसा है तो आप ImageMagick पायथन बाइंडिंग का उपयोग करने का प्रयास कर सकते हैं। – Qberticus

+0

रिक्त सीमा आकार निश्चित मान नहीं है, यह प्रति छवि भिन्न होता है। – jack

उत्तर

13

PIL के getbbox मेरे लिए काम कर रहा है

im.getbbox() => 4-टपल या कोई नहीं

गैर शून्य छवि में क्षेत्रों के सीमांकन बॉक्स गणना करता है। बाउंडिंग बॉक्स को 4-ट्यूपल के रूप में बाएं, ऊपरी, दाएं, और निचले पिक्सेल समन्वय को परिभाषित करने के रूप में वापस किया जाता है। अगर छवि पूरी तरह खाली है, तो यह विधि कोई भी नहीं लौटाती है।

कोड नमूना जिसकी मैंने कोशिश की, मैंने बीएमपी के साथ परीक्षण किया है, लेकिन इसे पीएनजी के लिए भी काम करना चाहिए।

>>> import Image 
>>> im=Image.open("test.bmp") 
>>> im.size 
(364, 471) 
>>> im.getbbox() 
(64, 89, 278, 267) 
>>> im2=im.crop(im.getbbox()) 
>>> im2.size 
(214, 178) 
>>> im2.save("test2.bmp") 
1

आप अपनी छवि के पंक्तियों और कोलों को खोजने के लिए PIL का उपयोग कर सकते हैं जो पूरी तरह से आपके सीमा रंग से बने होते हैं।

इस जानकारी का उपयोग करके, आप आसानी से इनलाइड छवि के विस्तार को निर्धारित कर सकते हैं।

पीआईएल फिर से आपको सीमा को हटाने के लिए छवि को फसल करने की अनुमति देगा।

3

https://gist.github.com/3141140

import Image 
import sys 
import glob 

# Trim all png images with alpha in a folder 
# Usage "python PNGAlphaTrim.py ../someFolder" 

try: 
    folderName = sys.argv[1] 
except : 
    print "Usage: python PNGPNGAlphaTrim.py ../someFolder" 
    sys.exit(1) 

filePaths = glob.glob(folderName + "/*.png") #search for all png images in the folder 

for filePath in filePaths: 
    image=Image.open(filePath) 
    image.load() 

    imageSize = image.size 
    imageBox = image.getbbox() 

    imageComponents = image.split() 

    if len(imageComponents) < 4: continue #don't process images without alpha 

    rgbImage = Image.new("RGB", imageSize, (0,0,0)) 
    rgbImage.paste(image, mask=imageComponents[3]) 
    croppedBox = rgbImage.getbbox() 

    if imageBox != croppedBox: 
     cropped=image.crop(croppedBox) 
     print filePath, "Size:", imageSize, "New Size:",croppedBox 
     cropped.save(filePath) 
0

मुझे लगता है कि यह @Frank ईद्भूजर के जवाब के पूरक के लिए आवश्यक है। वह एक अच्छा मुद्दा बनाता है, लेकिन इसमें छवि के बाहर अतिरिक्त सीमा रंग को ठीक तरह से फसल कैसे शामिल नहीं किया जाता है। मैंने पाया कि here। विशेष रूप से, मुझे यह उपयोगी पाया गया:

from PIL import Image, ImageChops 

def trim(im): 
    bg = Image.new(im.mode, im.size, im.getpixel((0,0))) 
    diff = ImageChops.difference(im, bg) 
    diff = ImageChops.add(diff, diff, 2.0, -100) 
    bbox = diff.getbbox() 
    if bbox: 
     return im.crop(bbox) 

im = Image.open("bord3.jpg") 
im = trim(im) 
im.show() 
+0

हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन यहां उत्तर के आवश्यक हिस्सों को शामिल करना बेहतर है और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक किए गए पृष्ठ में परिवर्तन होने पर लिंक-केवल उत्तर अमान्य हो सकते हैं। - [समीक्षा से] (/ समीक्षा/कम गुणवत्ता वाली पोस्ट/11453172) – niton

+0

विशिष्ट कोड शामिल करने के लिए संपादित किया गया। अच्छी बात। – AaronJPung

2

मुझे आज भी यही समस्या थी। पारदर्शी सीमाओं को फसल करने का मेरा समाधान यहां है। बस इस स्क्रिप्ट को अपने बैच .png फ़ाइलों के साथ अपने फ़ोल्डर में फेंक दें:

from PIL import Image 
import numpy as np 
from os import listdir 

def crop(png_image_name): 
    pil_image = Image.open(png_image_name) 
    np_array = np.array(pil_image) 
    blank_px = [255, 255, 255, 0] 
    mask = np_array != blank_px 
    coords = np.argwhere(mask) 
    x0, y0, z0 = coords.min(axis=0) 
    x1, y1, z1 = coords.max(axis=0) + 1 
    cropped_box = np_array[x0:x1, y0:y1, z0:z1] 
    pil_image = Image.fromarray(cropped_box, 'RGBA') 
    print(pil_image.width, pil_image.height) 
    pil_image.save(png_image_name) 
    print(png_image_name) 

for f in listdir('.'): 
    if f.endswith('.png'): 
     crop(f) 
संबंधित मुद्दे