कस्टम अपलोड निर्देशिका में प्रत्येक छवि का आकार?


11

मैं अपने कस्टम इमेज साइज को कस्टम फोल्डर में अपलोड करना चाहता हूं। फ़ोल्डर में चयनित चौड़ाई का नाम होना चाहिए। उदाहरण के लिए:

अगर मैं इन कस्टम आकारों को जोड़ूँ ...

add_image_size('custom-1', 300, 9999);
add_image_size('custom-2', 400, 9999);

यह अच्छा होगा कि अपलोड की गई छवियों को इस तरह अपलोड किया जाए:

http://www.my-site.com/wp-content/uploads/300/my-image.jpg
http://www.my-site.com/wp-content/uploads/400/my-image.jpg

क्या यह संभव है? मैंने केवल पाया है कि मैं upload_dir फ़िल्टर के साथ वैश्विक अपलोड फ़ोल्डर को बदल सकता हूं ।

जवाबों:


21

फिलिप, कुछ भी संभव है यदि आप अपना दिमाग इसमें लगाते हैं। आप वर्डप्रेस इमेज एडिटर क्लास को बढ़ाकर अपनी समस्या को हल कर सकते हैं।

नोट मैं वर्डप्रेस 3.7 का उपयोग कर रहा हूं - मैंने पहले संस्करणों में और नवीनतम 3.8 रिलीज में नीचे दिए गए किसी भी कोड की जांच नहीं की है।


छवि संपादक मूल बातें

वर्डप्रेस में दो अंतर्निहित वर्ग हैं जो छवि हेरफेर को संभालते हैं:

  • WP_Image_Editor_GD( /wp-includes/class-wp-image-editor-gd.php)
  • WP_Image_Editor_Imagick( /wp-includes/class-wp-image-editor-imagick.php)

ये दो वर्ग विस्तारित होते हैं WP_Image_Editorक्योंकि वे दोनों छवियों को लोड, आकार बदलने, संपीड़ित करने और सहेजने के लिए एक अलग छवि इंजन (क्रमशः जीडी और इमेजमैजिक) का उपयोग करते हैं।

डिफ़ॉल्ट रूप से WordPress सबसे पहले ImageMagick इंजन का उपयोग करने की कोशिश करेगा, जिसे PHP एक्सटेंशन की आवश्यकता होती है, क्योंकि यह आमतौर पर PHP के डिफ़ॉल्ट JD इंजन पर पसंद किया जाता है। अधिकांश साझा किए गए सर्वर में हालांकि ImageMagick एक्सटेंशन सक्षम नहीं है।


एक छवि संपादक जोड़ें

यह तय करने के लिए कि किस इंजन का उपयोग करना है, वर्डप्रेस एक आंतरिक फ़ंक्शन __wp_image_editor_choose()(स्थित /wp-includes/media.php) को कॉल करता है । यह फ़ंक्शन सभी इंजनों के माध्यम से देखता है कि कौन सा इंजन अनुरोध को संभाल सकता है।

फ़ंक्शन में एक फ़िल्टर भी होता है जो wp_image_editorsआपको अधिक छवि संपादकों को जोड़ने की अनुमति देता है जैसे:

add_filter("wp_image_editors", "my_wp_image_editors");
function my_wp_image_editors($editors) {
    array_unshift($editors, "WP_Image_Editor_Custom");

    return $editors;
}

ध्यान दें कि हम अपने कस्टम इमेज एडिटर क्लास को प्रिपेंड कर रहे हैं WP_Image_Editor_Customताकि वर्डप्रेस चेक करेगा कि क्या हमारा इंजन अन्य इंजनों के परीक्षण से पहले रिसाइज़िंग को हैंडल कर सकता है।


हमारी छवि संपादक बनाना

अब हम अपना स्वयं का छवि संपादक लिखने जा रहे हैं ताकि हम अपने लिए फ़ाइल नाम पर निर्णय ले सकें। फाइलिंग को विधि द्वारा नियंत्रित किया जाता है WP_Image_Editor::generate_filename()(दोनों इंजन इस विधि को विरासत में लेते हैं), इसलिए हमें अपने कस्टम वर्ग में इसे लिखना चाहिए।

चूंकि हम केवल फ़ाइल नाम बदलने की योजना बनाते हैं, इसलिए हमें मौजूदा इंजनों में से एक का विस्तार करना चाहिए, ताकि हमें पहिया को सुदृढ़ करना न पड़े। मैं WP_Image_Editor_GDअपने उदाहरण में विस्तार करूँगा, क्योंकि आपके पास शायद ImageMagick एक्सटेंशन सक्षम नहीं है। हालांकि कोड एक इमेजमैजिक सेटअप के लिए विनिमेय है। यदि आप अलग-अलग सेटअप पर थीम का उपयोग करने की योजना बना रहे हैं, तो आप दोनों को जोड़ सकते हैं।

// Include the existing classes first in order to extend them.
require_once ABSPATH.WPINC."/class-wp-image-editor.php";
require_once ABSPATH.WPINC."/class-wp-image-editor-gd.php";

class WP_Image_Editor_Custom extends WP_Image_Editor_GD {
    public function generate_filename($prefix = NULL, $dest_path = NULL, $extension = NULL) {
        // If empty, generate a prefix with the parent method get_suffix().
        if(!$prefix)
            $prefix = $this->get_suffix();

        // Determine extension and directory based on file path.
        $info = pathinfo($this->file);
        $dir  = $info['dirname'];
        $ext  = $info['extension'];

        // Determine image name.
        $name = wp_basename($this->file, ".$ext");

        // Allow extension to be changed via method argument.
        $new_ext = strtolower($extension ? $extension : $ext);

        // Default to $_dest_path if method argument is not set or invalid.
        if(!is_null($dest_path) && $_dest_path = realpath($dest_path))
            $dir = $_dest_path;

        // Return our new prefixed filename.
        return trailingslashit($dir)."{$prefix}/{$name}.{$new_ext}";
    }
}

ऊपर दिए गए अधिकांश कोड को सीधे WP_Image_Editorवर्ग से कॉपी किया गया और आपकी सुविधा के लिए टिप्पणी की गई। केवल वास्तविक परिवर्तन यह है कि प्रत्यय अब एक उपसर्ग है।

वैकल्पिक रूप से, आप प्रत्यय को एक उपसर्ग में बदलने के लिए कॉल parent::generate_filename()और उपयोग कर सकते हैं mb_str_replace(), लेकिन मुझे लगा कि गलत होने के लिए अधिक इच्छुक होगा।


मेटाडेटा के लिए नए रास्तों को सहेजना

अपलोड करने के बाद image.jpg, अपलोड फ़ोल्डर इस तरह दिखता है:

  • 2013/12/150x150/image.jpg
  • 2013/12/300x300/image.jpg
  • 2013/12/image.jpg

अब तक सब ठीक है। हालाँकि, जब मूलभूत फ़ंक्शन को कॉल किया जाता है wp_get_attachment_image_src(), तो हम देखेंगे कि सभी छवि आकार image.jpgनए निर्देशिका पथ के बिना संग्रहीत किए जाते हैं ।

हम छवि मेटाडेटा (जहाँ फ़ाइल नाम संग्रहीत हैं) में नए फ़ोल्डर संरचना को सहेजकर इस समस्या को हल कर सकते हैं। wp_generate_attachment_metadataडेटाबेस में डाले जाने से पहले डेटा विभिन्न फिल्टर ( दूसरों के बीच) से चलता है, लेकिन चूंकि हम पहले से ही एक कस्टम छवि संपादक को लागू कर रहे हैं, इसलिए हम छवि के आकार मेटाडेटा के स्रोत पर वापस जा सकते हैं WP_Image_Editor::multi_resize():। यह इस तरह से सरणियाँ उत्पन्न करता है:

Array (
    [thumbnail] => Array (
        [file]      => image.jpg
        [width]     => 150
        [height]    => 150
        [mime-type] => image/jpeg
    )

    [medium] => Array (
        [file]      => image.jpg
        [width]     => 300
        [height]    => 300
        [mime-type] => image/jpeg
    )
)

हम multi_resize()अपने कस्टम वर्ग में इस विधि को लिख देंगे :

function multi_resize($sizes) {
    $sizes = parent::multi_resize($sizes);

    foreach($sizes as $slug => $data)
        $sizes[$slug]['file'] = $data['width']."x".$data['height']."/".$data['file'];

    return $sizes;
}

जैसा कि आप देख सकते हैं, मैंने किसी भी कोड को बदलने की जहमत नहीं उठाई। मैं सिर्फ मूल विधि को कॉल करता हूं और इसे मेटाडेटा उत्पन्न करने देता हूं। फिर मैं परिणामस्वरूप सरणी के माध्यम से लूप करता हूं और fileप्रत्येक आकार के लिए मूल्य समायोजित करता हूं ।

अब wp_get_attachment_image_src($att_id, array(300, 300))लौटता है 2013/12/300x300/image.jpg। हुर्रे!


अंतिम विचार

मुझे उम्मीद है कि इसने आपके लिए एक अच्छा आधार प्रदान किया है। हालांकि, कृपया ध्यान दें कि यदि कोई चित्र निर्दिष्ट आकार (जैसे 280x300) से छोटा है, तो उत्पन्न प्रत्यय (हमारे मामले में उपसर्ग) और छवि का आकार 280x300 है, न कि 300x300। यदि आप बहुत से छोटे चित्र अपलोड करते हैं, तो आपको बहुत सारे अलग-अलग फ़ोल्डर मिलेंगे।

एक अच्छा समाधान यह होगा कि या तो एक फ़ोल्डर नाम ( small,, mediumवगैरह) के रूप में आकार के स्लग का उपयोग करें या कोड को गोल आकार में निकटतम पसंदीदा छवि आकार तक विस्तारित करें।

आपने नोट किया कि आप निर्देशिका नाम के रूप में सिर्फ चौड़ाई का उपयोग करना चाहते हैं। हालांकि चेतावनी दी जा सकती है - प्लगइन्स या थीम एक ही चौड़ाई के साथ दो अलग-अलग आकार उत्पन्न कर सकते हैं लेकिन अलग-अलग ऊंचाइयां।

इसके अलावा, आप सेटिंग्स> मीडिया के तहत 'या मेरे अपलोड को महीने में व्यवस्थित करें' और वर्ष आधारित फ़ोल्डरों को अक्षम करके या generate_filenameआगे भी हेरफेर करके वर्ष / माह फ़ोल्डर को हटा सकते हैं ।

उम्मीद है की यह मदद करेगा। सौभाग्य!


3
क्या जवाब है! : डी नाइस मैन!
फिलिप कुन्ह

1
आपका स्वागत है! मैं मान रहा था कि आपके पास कम से कम OOP और WP फ़िल्टर का अनुभव है, लेकिन अगर ऐसा कुछ है जिसे आप अभी तक नहीं समझते हैं, तो पूछने के लिए स्वतंत्र महसूस करें। इनाम के लिए धन्यवाद!
रोबर्ट डे

2
@ रोबर्ट फ्रैंकली, यह शानदार है। मैं मीडिया अपलोड सिस्टम में कार्रवाई और फिल्टर हुक की कमी पर अपने बालों को फाड़ रहा था। यह पूर्वव्यापी में स्पष्ट लगता है, लेकिन यह पूरी तरह से छवि संपादकों को ओवरराइड करने के लिए मेरे साथ नहीं हुआ था। ऐसा करने से एक में बहुत सारी समस्याएँ हल हो जाती हैं।
जोनाथन फिंगलैंड

1
@JonathanFingland Ha, मैं मानता हूं कि मुझे इस एक के लिए खरगोश के छेद से बहुत नीचे जाना था। सहायता करके हमें खुशी होगी!
रोबर्ट

छोटे नोट - कोड की अंतिम शांति में (सार्वजनिक फ़ंक्शन मल्टी_साइज़ ($ आकार)) कीवर्ड "सार्वजनिक" वेबसाइट को नीचे कर देता है। बस इसे हटा दें और यह फिर से ऊपर है। 2k17 और आपका जवाब अभी भी भयानक है, धन्यवाद !!
विरोधाभास

3

@ रॉबर्ट का उत्तर अलग-अलग निर्देशिकाओं में वर्डप्रेस द्वारा उत्पन्न वैकल्पिक आकारों को संग्रहीत करने के मेरे प्रयासों में एक दिव्य संसाधन था। मेरा कोड अपलोड निर्देशिका को / .media में भी बदलता है, इसलिए यदि आप ऐसा नहीं चाहते हैं तो इन पंक्तियों को संपादित करना सुनिश्चित करें। यह पहले पोस्टर के प्रश्न का सटीक उत्तर नहीं है, लेकिन उसी समस्या का वैकल्पिक समाधान प्रस्तुत करता है:

if ( !is_multisite() ) {
    update_option( 'upload_path', 'media' ); //to-do: add to options page
    define( 'UPLOADS', 'media' ); //define UPLOADS dir - REQUIRED
}
//don't “Organize my uploads into month- and year-based folders”
update_option( 'uploads_use_yearmonth_folders', '0' ); // to-do: add to options page

//create a custom WP_Image_Editor that handles the naming of files
function tect_image_editors($editors) {
    array_unshift( $editors, 'WP_Image_Editor_tect' );

    return $editors;
}

add_filter( 'wp_image_editors', 'tect_image_editors' );

require_once ABSPATH . WPINC . '/class-wp-image-editor.php';
require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php';

class WP_Image_Editor_tect extends WP_Image_Editor_GD {
    public function multi_resize($sizes) {
        $sizes = parent::multi_resize($sizes);

        $media_dir = trailingslashit( ABSPATH . UPLOADS );

        foreach($sizes as $slug => $data) {
            $default_name = $sizes[ $slug ]['file'];
            $new_name = $slug . '/' . preg_replace( '#-\d+x\d+\.#', '.', $data['file'] );

            if ( !is_dir( $media_dir . $slug ) ) {
                mkdir( $media_dir . $slug );
            }
            //move the thumbnail - perhaps not the smartest way to do it...
            rename ( $media_dir . $default_name, $media_dir . $new_name );

            $sizes[$slug]['file'] = $new_name;
        }

        return $sizes;
    }
}

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

संबंधित बोनस: सभी वर्डप्रेस जेनरेट किए गए थंबनेल डिलीट करने के लिए एक कच्ची उपयोगिता delete_deprecated_thumbs.php


1

मैंने वर्डप्रेस कोड के इन हिस्सों को देखा है और मुझे डर है कि मेरे पास कोई अच्छी खबर नहीं है।

2 वर्ग हैं:

  • WP_Image_Editor_GD
  • WP_Image_Editor_Imagick,

दोनों का सार WP_Image_Editorवर्ग।

ये कक्षाएं लागू करने की multi_resizeविधि है, जो अपलोड की गई एक से कई छवियों को उत्पन्न करने के लिए उपयोग की जाती है।

वास्तव में बुरी खबर यह है कि वहाँ कोई फिल्टर हुक नहीं हैं, जिसका उपयोग हम नई बनाई गई फ़ाइलों के लिए गंतव्य पथ को संशोधित करने के लिए कर सकते हैं।


कि एक शर्म की बात है। मैं अच्छे Imager.js को लागू करना चाहता था, लेकिन शायद इसके बिना काम नहीं करेगा।
फिलिप कुहन

ऐसा लगता है कि Imager.js छवियों को बॉट्स (Google, Facebook, आदि) के लिए अदृश्य बना देता है , इसलिए मैं इसका उपयोग करने के खिलाफ सलाह noscript
दूंगा

हम्म नहीं मुझे ऐसा नहीं लगता। आप आमतौर पर इमेज के src के साथ img-tags का उपयोग करते हैं। और आप अन्य छवियों-आकारों के एक सिंटैक्स के साथ अतिरिक्त डेटा-टैग जोड़ते हैं <img src="http://placehold.it/260" data-src="http://placehold.it/{width}" />:। और फिर स्क्रिप्ट जांचती है कि कौन सा आकार img का है और उसके लिए सबसे अच्छी छवि का आकार लोड करता है।
फिलिप कुहन

@ फिलिप्कन मैं भी निराश हूं। आपका विचार बहुत साफ था और मैं (के बाद विषय परिवर्तन ... में दर्द है को हटाने अप्रयुक्त थंबनेल) के लिए इसका इस्तेमाल करने के लिए अपलोड निर्देशिका को साफ़ रखने चाहता था
Krzysiek Dróżdż

@ KrzysiekDróżdz अरे मुझे लगता है कि मुझे मिल गया। नीचे मेरे जवाब को देखो। इस समाधान के साथ आप भी फ़ाइल नाम से एफ़टीपी छवियों के माध्यम से सॉर्ट कर सकते हैं और आसानी से अप्रयुक्त छवि आकारों को हटा सकते हैं।
फिलिप कुह्न

1

ठीक है, मुझे लगता है कि मैं समझ गया! सही नहीं है, लेकिन इसके लिए मैं इसे चाहता था। मेरे लिए केवल एक छवि की चौड़ाई महत्वपूर्ण है। मेरे लिए हाइट बेकार है। विशेष रूप से Imager.js को लागू करने के लिए छवि url में ऊंचाई परेशान कर रही है।

add_filter('image_make_intermediate_size', 'custom_rename_images');

function custom_rename_images($image) {
    // Split the $image path
    $info = pathinfo($image);
    $dir = $info['dirname'] . '/';
    $ext = '.' . $info['extension'];
    $name = wp_basename($image, '$ext');

    // New Name
    $name_prefix = substr($name, 0, strrpos($name, '-'));
    $size_extension = substr($name, strrpos($name, '-') + 1);
    $image_sizes = explode('x', $size_extension);
    $image_width = $image_sizes[0];
    $new_name = $dir . $image_width . '-' . $name_prefix . $ext;

    // Rename the intermediate size
    $did_it = rename($image, $new_name);

    // Return if successful
    if ($did_it) return $new_name;

    // Return on fail
    return $image;
}

इस कोड के साथ फ़ाइल नाम इस प्रकार हैं:

http://www.my-site.com/wp-content/uploads/300-my-image.jpg
http://www.my-site.com/wp-content/uploads/400-my-image.jpg

यह नहीं , फ़ाइल नाम के लिए एक सबफ़ोल्डर को जोड़ने के लिए है, तो मैं हमेशा मूल स्रोत एक पोस्ट / पृष्ठ में छवियों को जोड़ बजाय प्रयोग किया जाएगा, क्योंकि संभव। और हटाने पर इन छवियों को हटाने से भी काम नहीं चलेगा। मुझे यकीन नहीं है कि क्यों।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.