2013-02-24 30 views
15

मैं सिम्फनी 2.1 के साथ LiipImagineBundle का उपयोग कर रहा हूं और स्थायी फाइल सिस्टम स्थान पर सहेजने से पहले अपलोड पर उपयोगकर्ता अपलोड की गई छवियों का आकार बदलना चाहता हूं (मेटाडेटा को पट्टी करने के लिए, जेपीजी प्रारूप लगाएं, और फ़ाइल के आकार को सीमित करें)। मुझे नियंत्रक से 'स्ट्रिप' और 'आकार बदलें' फ़िल्टर को कॉल करना होगा और फिर फ़िल्टर किए गए चित्र को अस्थायी स्थान से फाइल सिस्टम में मेरे चयन के फ़ोल्डर में सहेजना होगा।अपलोड के बाद छवि का आकार बदलने के लिए LiipImagineBundle का उपयोग करें?

मैंने LiipImageBundle Controller as a service as indicated in the bundle's readme का उपयोग करने की कोशिश की लेकिन कहा जाता है कि कार्रवाई मुख्य रूप से कैश निर्देशिका में फ़िल्टर की गई छवि बनाने के लिए होती है जब छवि को प्रदर्शित करने के लिए अनुरोध किया जाता है (अपलोड करने के दौरान फ़िल्टरिंग के लिए इसका उपयोग करना एक और मामला है)। मैंने इसे किसी भी तरह से लागू करने की कोशिश की, और इसे काम करने के लिए मिला। फ़िल्टर को लागू करने में सक्षम होने के लिए मुझे पहले वेब सर्वर की निर्देशिका में वेब सर्वर की php अस्थायी निर्देशिका से फ़ाइल को स्थानांतरित करना था। दूसरा, मैंने फ़िल्टर को लागू किया और प्रारंभिक unfiltered फ़ाइल हटा दिया (अनलिंक())। अंत में, मुझे फाइल सिस्टम में स्थायी स्थान पर फ़िल्टर की गई फ़ाइल (नाम बदलें) को स्थानांतरित करना पड़ा। फ़ाइल को दो बार स्थानांतरित करना आवश्यक था, फ़िल्टर को एक बार लागू करें, और इसे सभी काम करने के लिए 1 फ़ाइल हटाएं (अनलिंक करें)। अपलोड पर बंडल का उपयोग करने के लिए कोई बेहतर तरीका है (इंटरमीडिएट चाल की आवश्यकता नहीं है)?

liip_imagine: 
    filter_sets: 
     my_filter: 
      format: jpeg 
      filters: 
       strip: ~ 
       thumbnail: { size: [1600, 1000], mode: inset } 

A similar question was asked for the ImagineAvalancheBundle लेकिन कोई अधिक से अधिक जानकारी दिए गए हैं:

class MyController extends Controller 
{ 
    public function new_imageAction(Request $request) 
    { 
     $uploadedFile = $request->files->get('file'); 
     $tmpFolderPathAbs = $this->get('kernel')->getRootDir() . '/../web/uploads/tmp/'; 
     $tmpImageNameNoExt = rand(); 
     $tmpImageName = $tmpImageNameNoExt . '.' . $fileExtension; 
     $uploadedFile->move($tmpFolderPathAbs, $tmpImageName); 
     $tmpImagePathRel = '/uploads/tmp/' . $tmpImageName; 
     // Create the filtered image in a tmp folder: 
     $this->container->get('liip_imagine.controller')->filterAction($request, $tmpImagePathRel, 'my_filter'); 
     unlink($tmpFolderPathAbs . $tmpImageName); 
     $filteredImagePathAbs = $this->get('kernel')->getRootDir() . '/../web/uploads/cache/my_filter/uploads/tmp/' . $tmpImageNameNoExt . '.jpeg'; 
     $imagePath = $imageManagerResponse->headers->get('location'); 
     // define permanent location ($permanentImagePathAbs)... 
     rename($filteredImagePathAbs, $permanentImagePathAbs); 
    } 
} 

एप्लिकेशन/config/config.yml में मेरे फिल्टर इस प्रकार है। शायद another service from the here provided list लागू करना एक बेहतर समाधान है?

+0

क्या तुमने कभी एक बेहतर समाधान मिला:

use Liip\ImagineBundle\Model\Binary; 

उसके बाद निम्न कोड का उपयोग करें? मुझे भी यही चाहिए। फ़िल्टर अच्छी तरह से काम करता है, लेकिन जब मेरे पास बहुत सारे थंबनेल होते हैं तो प्रदर्शन बहुत अच्छा नहीं होता है, जिससे उन्हें कैश से स्थानांतरित समय पर ज्ञात स्थान पर ले जाया जाता है, जो नाटकीय रूप से चीजों को गति देता है। –

+0

@ पीटरवॉस्टर: मुझे एक और समाधान नहीं मिला, लेकिन ऊपर वर्णित एक व्यक्ति ठीक काम करता है (मैंने इसे इस तरह रखा है)। – RayOnAir

+0

मैं एक समाधान पर काम कर रहा हूं और यह काम करता है जब यहां काम करेगा। –

उत्तर

16

तो लीप इमेजिनबंडल के साथ अपलोड पर थंबनेल बनाने का एक तरीका यहां है।

/** 
    * Write a thumbnail image using the LiipImagineBundle 
    * 
    * @param Document $document an Entity that represents an image in the database 
    * @param string $filter the Imagine filter to use 
    */ 
    private function writeThumbnail($document, $filter) { 
     $path = $document->getWebPath();        // domain relative path to full sized image 
     $tpath = $document->getRootDir().$document->getThumbPath();  // absolute path of saved thumbnail 

     $container = $this->container;         // the DI container 
     $dataManager = $container->get('liip_imagine.data.manager'); // the data manager service 
     $filterManager = $container->get('liip_imagine.filter.manager');// the filter manager service 

     $image = $dataManager->find($filter, $path);     // find the image and determine its type 
     $response = $filterManager->get($this->getRequest(), $filter, $image, $path); // run the filter 
     $thumb = $response->getContent();        // get the image from the response 

     $f = fopen($tpath, 'w');          // create thumbnail file 
     fwrite($f, $thumb);            // write the thumbnail 
     fclose($f);              // close the file 
    } 

यह भी सीधे कॉल पुस्तकालय कार्यों कल्पना कीजिए अगर आप कोई अन्य कारण LiipImagineBundle शामिल करने के लिए किया था के द्वारा किया जा सकता है: चाल उनके अन्य सेवाओं में से कुछ का उपयोग करने के लिए है। मैं शायद भविष्य में उस पर ध्यान रखूंगा, लेकिन यह मेरे मामले के लिए काम करता है और बहुत अच्छा प्रदर्शन करता है।

+0

इस उत्तर को पोस्ट करने के लिए धन्यवाद। जैसे ही मेरे पास कोशिश करने के लिए थोड़ा समय है, मैं आपको बता दूंगा कि यह कैसा चल रहा है! – RayOnAir

+0

+1: आपने फ़िल्टर लागू करने और इच्छित छवि को वांछित गंतव्य पर सहेजने के लिए सही सेवाओं की पहचान की है। मेरे प्रश्न का पूरा जवाब फाइल सिस्टम में एक अस्थायी छवि को सहेजने के लिए मेरे चरणों का संयोजन है और फ़िल्टर को लागू करने के लिए आपके चरणों और परिवर्तित छवि को अंतिम गंतव्य पर सहेजने के लिए है (क्योंकि मेरा प्रश्न सीधे अपलोड की गई छवि पर फ़िल्टर लगाने के लिए है इसे फाइल सिस्टम में सहेजने से पहले इसे आकार देने के लिए)। आपका समाधान थंबनेल बनाने और उन्हें उस छवि से संग्रहीत करने के लिए है जो पहले से ही फाइल सिस्टम में है। – RayOnAir

+0

ध्यान दें कि फ़िल्टर को उस छवि पर लागू करना प्रतीत नहीं होता है जो पहले से ही वेब निर्देशिका में किसी फ़ोल्डर में नहीं है, जब तक कि विशेष एक्सेस विशेषाधिकार सेट न हों। – RayOnAir

0

यह देखते हुए कि मुझे बेहतर तरीका नहीं मिला, मैंने प्रश्न विवरण में वर्णित समाधान रखा। यह समाधान प्रदर्शन स्टैंड पॉइंट से इष्टतम प्रतीत नहीं होता है (इसे फ़ाइल को दो बार स्थानांतरित करने की आवश्यकता होती है, फ़िल्टर को एक बार लागू करें, और 1 फ़ाइल को अनलिंक करें), लेकिन यह काम पूरा हो जाता है।

अद्यतन:

के रूप में (के रूप में फ़िल्टर छवि अंतिम गंतव्य के लिए सीधे सहेजा जाता है कि समाधान अधिक इष्टतम है) नीचे दिखाया गया

मैं सेवाओं पीटर वूस्टर के जवाब में संकेत का उपयोग करने के लिए अपने कोड बदल गया है,:

class MyController extends Controller 
{ 
    public function new_imageAction(Request $request) 
    { 
     $uploadedFile = $request->files->get('file'); 
     // ...get file extension and do other validation... 
     $tmpFolderPathAbs = $this->get('kernel')->getRootDir() . '/../web/uploads/tmp/'; // folder to store unfiltered temp file 
     $tmpImageNameNoExt = rand(); 
     $tmpImageName = $tmpImageNameNoExt . '.' . $fileExtension; 
     $uploadedFile->move($tmpFolderPathAbs, $tmpImageName); 
     $tmpImagePathRel = '/uploads/tmp/' . $tmpImageName; 
     // Create the filtered image: 
     $processedImage = $this->container->get('liip_imagine.data.manager')->find('my_filter', $tmpImagePathRel); 
     $filteredImage = $this->container->get('liip_imagine.filter.manager')->get($request, 'my_filter', $processedImage, $tmpImagePathRel)->getContent(); 
     unlink($tmpFolderPathAbs . $tmpImageName); // eliminate unfiltered temp file. 
     $permanentFolderPath = $this->get('kernel')->getRootDir() . '/../web/uploads/path_to_folder/'; 
     $permanentImagePath = $permanentFolderPath . 'my_image.jpeg'; 
     $f = fopen($permanentImagePath, 'w'); 
     fwrite($f, $filteredImage); 
     fclose($f); 
    } 
} 
+0

आप एक ऐसी सेवा लिख ​​सकते हैं जो आपके लिए पूरी चीज करे और उसके बाद लीप इमाजिन की बजाय इसका उपयोग करें। –

7

@ पीटर वूस्टर का संशोधित संस्करण, और इसे अधिक सामान्य बना दिया ताकि अगर कोई छवि इकाई के बिना इसका उपयोग कर रहा है तो वह आसानी से बेनिफेट ले सकता है। मैं यहां दो संस्करण दे रहा हूं, जिसका उपयोग यूटिलिटी या गैर-नियंत्रक वर्ग में रखा जा सकता है। और दूसरा संस्करण नियंत्रक कक्षाओं के लिए है। यह अब आप पर निर्भर है जहां आप पसंद करते हैं :)

नियंत्रक के बाहर उपयोग करने के लिए उदा। इसे उपयोगिता कक्षाओं में रखते हुए

/** 
* Write a thumbnail image using the LiipImagineBundle 
* 
* @param Document $fullSizeImgWebPath path where full size upload is stored e.g. uploads/attachments 
* @param string $thumbAbsPath full absolute path to attachment directory e.g. /var/www/project1/images/thumbs/ 
* @param string $filter filter defined in config e.g. my_thumb 
* @param Object $diContainer Dependency Injection Object, if calling from controller just pass $this 
*/ 
public function writeThumbnail($fullSizeImgWebPath, $thumbAbsPath, $filter, $diContainer) { 
    $container = $diContainer; // the DI container, if keeping this function in controller just use $container = $this 
    $dataManager = $container->get('liip_imagine.data.manager'); // the data manager service 
    $filterManager = $container->get('liip_imagine.filter.manager'); // the filter manager service 
    $image = $dataManager->find($filter, $fullSizeImgWebPath);     // find the image and determine its type 
    $response = $filterManager->applyFilter($image, $filter); 

    $thumb = $response->getContent();        // get the image from the response 

    $f = fopen($thumbAbsPath, 'w');          // create thumbnail file 
    fwrite($f, $thumb);            // write the thumbnail 
    fclose($f);              // close the file 
} 

नियंत्रक में उपयोग करने के लिए उदा। कॉमनकंट्रोलर या कोई अन्य नियंत्रक।

/** 
* Write a thumbnail image using the LiipImagineBundle 
* 
* @param Document $fullSizeImgWebPath path where full size upload is stored e.g. uploads/attachments 
* @param string $thumbAbsPath full absolute path to attachment directory e.g. /var/www/project1/images/thumbs/ 
* @param string $filter filter defined in config e.g. my_thumb 
*/ 
public function writeThumbnail($fullSizeImgWebPath, $thumbAbsPath, $filter) { 
    $container = $this->container; 
    $dataManager = $container->get('liip_imagine.data.manager'); // the data manager service 
    $filterManager = $container->get('liip_imagine.filter.manager'); // the filter manager service 
    $image = $dataManager->find($filter, $fullSizeImgWebPath);     // find the image and determine its type 
    $response = $filterManager->applyFilter($image, $filter); 

    $thumb = $response->getContent();        // get the image from the response 

    $f = fopen($thumbAbsPath, 'w');          // create thumbnail file 
    fwrite($f, $thumb);            // write the thumbnail 
    fclose($f);              // close the file 
} 
+0

मुझे अपने बिटमैनी वैंप स्टैक पर अपना कोड आज़माते समय फॉलोइंग त्रुटि मिल रही है, छवि अपलोड/माइम प्रकार के इमेज प्रकार/आईएमजी -5535_05052015_923_c2a1a.JPG छवि/xxx को इनोड/एक्स-रिक्त होना चाहिए। क्या आप इसके साथ मेरी मदद कर सकते हैं? – Adam

+0

@Adam कुछ अन्य छवियों को अपलोड करने का प्रयास करें और साथ ही साथ किसी अन्य प्रकार के साथ, क्योंकि छवि माइम प्रकार दूषित दिखता है या कुछ अन्य समस्याएं हैं। –

0

मैंने एक बंडल लिखा है जो इस समस्या को ठीक करता है।जबकि VichUploaderBundle ओआरएम के लाइफसाइक्ल कॉलबैक का उपयोग करके आसान अपलोडिंग प्रदान करता है, LiipImagine आकार बदलने पर एक अच्छा काम करता है। https://github.com/RSSfeed/VichImagineBundle

कैसे केवल कुछ ही मिनटों में इसे लागू करने पर short readme देखें:

यहाँ यह का संयोजन है।

0
इसके बजाय liip डेटा प्रबंधक का उपयोग कर फ़ाइल लोड करने के

, अपलोड की गई फ़ाइल से बाइनरी वस्तु liip बनाएँ:

   // Generate a unique name for the file before saving it 
       $fileName = md5(uniqid()) . '.' . $uploadedFile->guessExtension(); 

       $contents = file_get_contents($uploadedFile); 

       $binary = new Binary(
        $contents, 
        $uploadedFile->getMimeType(), 
        $uploadedFile->guessExtension() 
       ); 

       $container = $this->container; 
       $filterManager = $container->get('liip_imagine.filter.manager'); // the filter manager service 
       $response = $filterManager->applyFilter($binary, 'my_thumb'); 

       $thumb = $response->getContent();        // get the image from the response 

       $f = fopen($webRootDir .'/images_dir/' . $fileName, 'w');          // create thumbnail file 
       fwrite($f, $thumb);            // write the thumbnail 
       fclose($f);              // close the file