2010-07-27 14 views
20

की प्रत्येक फ्रेम बना रहे ये पैलेट चक्र छवियों लुभावनी हैं: http://www.effectgames.com/demos/canvascycle/?sound=0एक HTML5 कैनवास

मैं डेस्कटॉप पृष्ठभूमि में इनमें से कुछ (या सभी) करना चाहते हैं।

मैं एक एनिमेटेड GIF संस्करण इस्तेमाल कर सकते हैं, लेकिन मैं कैसे कैनवास "एनीमेशन" से प्राप्त करने के लिए है कि पता नहीं है। क्या अभी तक कुछ भी उपलब्ध है जो इन पंक्तियों के साथ कुछ कर सकता है (उस लिंक के लिए सतही रूप से और आम तौर पर बोल रहा है)।

+4

उन अद्भुत हैं:

phantomjs SaveCanvasFrame.js 

फिर ImageMagick

convert *.png animated.gif 

ये हम चले उपयोग करें! मुझे जवाब देने के सबसे नज़दीक यह था: http://stackoverflow.com/questions/923885/capture-html-canvas-as-gif-jpg-png-pdf समस्या यह है कि ऐसा लगता है कि कार्यान्वयन केवल स्थैतिक के लिए अनुमति देता है छवियों, एनिमेशन नहीं। शायद एक अलग छवि के रूप में प्रत्येक "फ्रेम" को प्रोग्रामिक रूप से कैप्चर करना संभव है और फिर उन्हें एक जीआईएफ के रूप में एक साथ सिलाई करना संभव है? – peterjmag

+0

जो सिर्फ काम कर सकता है, शायद आपको अपनी टिप्पणी को उत्तर देना चाहिए ताकि अगर कोई और कोई विचार न आए तो मैं आपको अंक दे सकता हूं :) –

+3

मेरी कोशिश करें: http://imgur.com/p9gcV।gif –

उत्तर

24

मैं एक समाधान है, लेकिन यह आप Firefox में Javascript कंसोल (Firebug plugin स्थापित) जैसे Chrome या Safari से परिचित जा रहा है पर निर्भर है।

मामले में आप, यह गूगल रहे हैं, या सिर्फ सही पृष्ठ पर कहीं भी क्लिक करने के लिए प्रयास करते हैं, चुनें "तत्व का निरीक्षण" और "कंसोल" के लिए देखो ...

क्या कोड है:

यह आप CANVAS तत्व हर 1/एक दूसरे की 10 वीं के 10 स्क्रीन पकड़ लेता है लेने के लिए अनुमति देता है। इन दोनों मानों को आसानी से संशोधित किया जाता है क्योंकि आप उन पुनरावृत्तियों की संख्या को ढूंढने के लिए ट्विक कर सकते हैं जिन्हें आप प्राप्त करना चाहते हैं। उदाहरण के लिए, कैनवास तत्व आईडी 'mycanvas' है।

एक बार जब यह स्क्रीन-grabs हो जाता है तो यह छवियों को पृष्ठ में आउटपुट करता है। उस समय आप व्यक्तिगत छवियों को बचा सकते हैं।

Javascript कंसोल में कोड निम्न कोड में

पेस्ट चल रहा है:

var canvas = document.getElementById("mycanvas"); 
var shots = []; 
var grabLimit = 10; // Number of screenshots to take 
var grabRate = 100; // Miliseconds. 500 = half a second 

var count  = 0; 

function showResults() { 
    //console.log(shots); 
    for (var i=0; i<shots.length; i++) { 
     document.write('<img src="' + shots[i] + '"/>\n'); 
    } 
} 

var grabber = setInterval(function(){ 
    count++; 

    if (count>grabLimit) { 
    clearInterval(grabber); 
    showResults(); 
    } 

    var img  = canvas.toDataURL("image/png"); 
    shots.push(img); 
}, grabRate); 

और प्रेस यह निष्पादित करने के लिए CTRL-दर्ज करें।

इसे चलाने में कुछ सेकंड लग सकते हैं इसलिए कृपया धैर्य रखें।

इसके बाद आपको छवि मैगिक के माध्यम से एनिमेटेड जीआईएफ बनाने के लिए सभी आवश्यक फ्रेम (किसी भी अधिक) होना चाहिए, यह वेबसाइट MakeAGif.com, या अन्य ऐप।

साइड नोट

किसी कारण से आप पीएनजी के बजाय जेपीजी की GIF के रूप में उत्पादन के लिए की जरूरत है तो बस अद्यतन करते हैं, के रूप में की जरूरत है, इस: इनमें से

var img  = canvas.toDataURL("image/png"); 

से है:

var img  = canvas.toDataURL("image/gif"); 
var img  = canvas.toDataURL("image/jpg"); 

आउटपुट के लिए समर्थन gif या jpg सभी ब्राउज़रों में नहीं हो सकता है (सबसे अधिक होना चाहिए)।

(BIG) अद्यतन # 1

सबसे पहले, मैं इसे अद्यतन करने की तुलना में बरकरार ऊपर कोड रखने कर रहा हूँ बल्कि इसलिए कि दोनों दृष्टिकोण दूसरों के लिए उपयोगी हो सकता है।

दूसरा, यह नया कोड समस्या को हल नहीं करता है। यह एक तरह की कमी है लेकिन एक बड़ी कमी है। यह एक एनिमेटेड जीआईएफ (यिपे!) बनाता है लेकिन यह हरे रंग के विभिन्न रंगों में (बूओ!) बनाता है। सुनिश्चित नहीं है कि कैसे/क्यों, लेकिन शायद कोई इसे यहां से ले जा सकता है और देख सकता है कि मैंने क्या चूक लिया है।

तो यहाँ हम चले ... वही नियम लागू - कॉपी और यह एक ब्राउज़र की Javascript कंसोल (यह फ़ायरफ़ॉक्स लेकिन गूगल क्रोम में lags इसकी बहुत तेजी से ... 10 सेकंड या तो चलाने के लिए) में पेस्ट करें।

var jsf = ["/Demos/b64.js", "LZWEncoder.js", "NeuQuant.js", "GIFEncoder.js"]; 
var head = document.getElementsByTagName("head")[0]; 

for (var i=0;i<jsf.length;i++) { 
    var newJS = document.createElement('script'); 
    newJS.type = 'text/javascript'; 
    newJS.src = 'http://github.com/antimatter15/jsgif/raw/master/' + jsf[i]; 
    head.appendChild(newJS); 
} 

// This post was very helpful! 
// http://antimatter15.com/wp/2010/07/javascript-to-animated-gif/ 

var w = setTimeout(function() { // give external JS 1 second of time to load 

    console.log('Starting'); 

    var canvas = document.getElementById("mycanvas"); 
    var context = canvas.getContext('2d'); 
    var shots = []; 
    var grabLimit = 10; // Number of screenshots to take 
    var grabRate = 100; // Miliseconds. 500 = half a second 
    var count  = 0; 

    function showResults() { 
     console.log('Finishing'); 
     encoder.finish(); 
     var binary_gif = encoder.stream().getData(); 
     var data_url = 'data:image/gif;base64,'+encode64(binary_gif); 
     document.write('<img src="' +data_url + '"/>\n'); 
    } 

    var encoder = new GIFEncoder(); 
    encoder.setRepeat(0); //0 -> loop forever, 1+ -> loop n times then stop 
    encoder.setDelay(500); //go to next frame every n milliseconds 
    encoder.start(); 

    var grabber = setInterval(function(){ 
     console.log('Grabbing '+count); 
     count++; 

     if (count>grabLimit) { 
     clearInterval(grabber); 
     showResults(); 
     } 

     var imdata = context.getImageData(0,0,canvas.width,canvas.height); 
     encoder.addFrame(context); 

    }, grabRate); 

}, 1000); 

यह कुछ उपयोगी कोड, संकेत और JS फ़ाइलों को इस ब्लॉग पोस्ट JavaScript to (Animated) GIF में संदर्भित उपयोग करता है। मैं सीधे कुछ जेएस फाइलों का उपयोग करता हूं लेकिन यदि आप इसका उपयोग करने जा रहे हैं तो आपको इन स्थानीय रूप से कॉपी करना चाहिए।

मेरे लिए उत्पादन इस GIF था: alt text

तो इसकी कुछ नहीं, बल्कि तुम क्या जरूरत है ...

+0

आप इसे घोषित करने के बाद 'संदर्भ' चर का कभी भी उपयोग नहीं करते हैं। क्या इसका कोई उपयोग है? –

+1

ओह। आप सही हे। इसे हटाने के लिए भूल गए। मैंने तदनुसार कोड अपडेट किया है। ध्यान देने के लिए धन्यवाद। – donohoe

+0

यह एक शानदार समाधान है, लेकिन मैं यह नहीं समझ सकता कि फ़ाइलों को वास्तव में छवियों को कैसे सहेजना है। न तो डाउनथीम या ओपेरा लिंक छवियों को देखने में सक्षम हैं। –

1

अफसोस की बात है, art creator के अनुसार, तस्वीर के विभिन्न हिस्सों के कारण विभिन्न चक्रों के कारण इसे जीआईएफ एनीमेशन में परिवर्तित करना संभव नहीं है।

+1

मुझे लगता है कि, चूंकि एनिमेटेड फ्रेम के पार जीआईएफ के प्रभावशाली ढंग से मेल खाने वाले पिक्सेल को संकुचित कर सकता है, तथ्य यह है कि यह हजारों फ्रेम लेता है वास्तव में कलाकार की संदिग्ध समस्या के रूप में नहीं है। बेशक, उसका सौंदर्य अर्थव्यवस्था का पक्ष लेता है, इसलिए वह समस्या पर हार्ड ड्राइव स्पेस फेंकने का स्वाभाविक रूप से विरोध करेगा, लेकिन इसका मतलब यह नहीं है कि यह संभव नहीं है! – WCWedin

+0

यह है - बस सीधे नहीं। डब्ल्यूसीडब्ल्यूडिन ने जो भी कहा, उसे +1 करें। – donohoe

+0

ठीक है, तो आपको बस सभी एनीमेशन चक्रों के सबसे कम आम denominator को समझने की जरूरत है। यह उन छवियों की संख्या होगी जिन्हें आपको सहेजने की आवश्यकता है। – syockit

12

संपादित: अंत में उपयोग करने के लिए है कि कोड डाल दिया, यहाँ परिणाम है:

alt text

Imagick एक बड़ी छवि उत्पन्न, तो मैं आगे चला गया और जिम्प के साथ अनुकूलित।

var canvas = document.getElementById("mycanvas"); 
var shots = []; 
var grabLimit = 30; // Number of screenshots to take 
var grabRate = 100; // Miliseconds. 500 = half a second 

var count  = 0; 

function postResults() { 
    console.log("START---------"); 
    for (var i = 0; i < shots.length; i++) { 
     document.write(shots[i]+"<br />"); 
    }  
    console.log("END-----------"); 
} 

var grabber = setInterval(function(){ 
    count++; 

    if (count>grabLimit) { 
    clearInterval(grabber); 
    postResults(); 
    } 

    var img  = canvas.toDataURL("image/png"); 
    shots.push(img.replace("data:image/png;base64,","")); 
}, grabRate); 

यह स्क्रीन करने के लिए बेस 64 तार का एक समूह लिखेंगे:

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


PHP का उपयोग करके बहुत कठिन नहीं हो सकता है।

  1. जेएस के साथ प्रत्येक फ्रेम के लिए dataURL (base64 एन्कोडेड स्ट्रिंग) पकड़ें और इसे सर्वर पर भेजें।
  2. बेस 64 तार डिकोड और वस्तुओं Imagick लिए उन्हें बदलने।
  3. एक नया Imagick वस्तु के लिए फ्रेम के रूप में इन Imagick वस्तुओं जोड़ें।
  4. एक GIF के रूप में फाइल सिस्टम के लिए Imagick वस्तु की बचत करें। मैं एक साल या दो लोगों के लिए बहुत पीएचपी नहीं लिखा है

    <?php 
    $imageData = array_map('rtrim', file('data.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)); //base 64 strings separated by newlines 
    $delay = 100; 
    $filename = 'coolmoviebro.gif'; 
    $gif = new Imagick(); 
    
    for($i = 0; $i < count($imageData); $i++) { 
        $tempImg = new Imagick(); 
        $tempImg->readimageblob(base64_decode($imageData[$i])); 
        $gif->addImage($tempImg); 
    } 
    
    $gif->setFormat('gif'); 
    $gif->setImageDelay($delay); 
    $gif->writeImages($filename, true); 
    
    ?> 
    

    :

के बाद माइकल पहले से ही एक अच्छा जे एस समाधान तैनात, मैं अगर आप इसे स्वचालित बनाना चाहते सर्वर साइड कोड जोड़ेंगे सब कुछ जांचने के लिए सुनिश्चित करें और इतने पर।

+1

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

+1

@WCWedin: मैं सहमत हूं - यद्यपि यह एनीमेशन के अंत तक बहुत चिकनी है, जहां यह समाप्त नहीं हुआ था, जहां चक्र मूल रूप से शुरू हुआ था, जैसा कि अपेक्षित था। मैंने इसमें और अधिक विचार किया होगा, लेकिन जीआईएफ उत्पन्न करने के लिए "अवधारणा का सबूत" पर्याप्त था, और यह भी विचार कर रहा था कि जब मैं छवि के साथ आया था, तो जवाब पहले से ही चुना गया था, वहां थोड़ा प्रेरणा थी जारी रखने के लिए। हालांकि अगर कोई मुझे सही फ्रेम डेटा प्राप्त कर सकता है, तो मुझे gif को पुन: उत्पन्न करने में खुशी होगी। अगर मेरे पास समय लगता है तो मुझे लगता है कि मैं स्रोत को एक नज़र देख सकता हूं कि मैं एक पूर्ण चक्र निकाल सकता हूं या नहीं। –

2

मैं कोड पर एक नज़र ले लिया है, और ऐसा लगता है जैसे कि यह संभव हो जाना चाहिए थोड़ा हैकिंग के साथ।

पैलेट में चक्र वस्तुओं की सूची को देखकर। चक्र, आप चक्र के साथ प्रत्येक चक्र की चक्र लंबाई को समझने में सक्षम होना चाहिए। High, cycle.low, और cycle.rate फ़ील्ड। उस ने कहा, आपको cycle.reverse के लिए छह संभावित मानों में से प्रत्येक के लिए एक अलग एल्गोरिदम की आवश्यकता होगी।

एक बार जब आप सूची में प्रत्येक चक्र की लंबाई पता (मिलीसेकेंड में, अगर मैं कोड सही तरीके से पढ़ रहा हूँ), आप चक्र लंबाई की सब से छोटा आम गुणक है, जो आप कुल लंबाई कहते थे मिल सकता है एनीमेशन का। अभ्यास में, हालांकि, आप कम नमूना अवधि प्राप्त करने के लिए पहले अपनी नमूना अवधि से पहले फर्श-विभाजित करना चाहते हैं, (कहें, दस फ्रेम के लिए 100 मिलीसेकंड)।

फिर रिग main.js में चेतन समारोह एक tickCount पैरामीटर लेने के लिए और पारित कि palette.cycle में, बजाय वास्तविक समय के आधार पर कुछ भी का उपयोग करने के लिए। प्रत्येक पुनरावृत्ति के साथ अपने नमूना अवधि द्वारा टिक गिनती बढ़ाएं।

वहाँ से, आप बिटमैप वर्ग की विधि प्रस्तुत करना संशोधित करने के लिए सक्षम होना चाहिए, एक फाइल करने के लिए कैनवास चीर करने के लिए आवश्यक तर्क जोड़ने। ऐसे पुस्तकालय दिखाई देते हैं जो आपके लिए यह अंतिम बिट प्रबंधित कर सकते हैं। मैं फ़ाइल नाम के रूप में टिक गिनती का उपयोग करके फ़ाइलें बचत की सिफारिश करेंगे (उन्हें क्रम में रखने के लिए पर्याप्त पहले शून्य।) सभी छवियों को एक एनिमेटेड GIF में एक साथ सिलाई सही सॉफ्टवेयर का उपयोग कर एक बैच कार्य के रूप में निष्पादित करने के लिए संभव हो सकता है।

बेशक

, मैं वास्तव में इस प्रयास नहीं किया है। उदाहरण के लिए, आप यह सुनिश्चित करने के लिए जांच कर सकते हैं कि आप एक महाकाव्य चक्र की लंबाई के साथ एनीमेशन पर ठोकर नहीं डालते हैं और अपनी हार्ड ड्राइव पर लाखों छवियां बनाते हैं।

एक तरफ के रूप में, आप थोड़ा और काम कर सकते हैं, अगले अपडेट तक सटीक समय निकाल सकते हैं और अनियमित नमूने ले सकते हैं, लेकिन आपको यह समझना होगा कि उस देरी की जानकारी को कैसे स्टोर किया जाए ताकि आप पूरा जीआईएफ इकट्ठा करने के लिए इसका इस्तेमाल करें।

1

Try PhantomJS

यह स्क्रिप्ट 100 फ्रेम बचाता है।

var webPage = require('webpage'); 
var fs = require('fs'); 
var page = webPage.create(); 

var NB_FRAME = 100; 
var current = 0; 

page.open('http://www.effectgames.com/demos/canvascycle/?sound=0', 
function(status) { 
    if (status === "success") { 
    var current = 0; 
    var grabber = setInterval(function() { 
     var frame = page.evaluate(function() { 
     return document.getElementById('mycanvas').toDataURL("image/png").split(",")[1]; 
     }); 
     fs.write("./frame-" + current + ".png",atob(frame), 'wb'); 
    if (++current === NB_FRAME) { 
    window.clearInterval(grabber); 
    phantom.exit(0); 
    } 
    }, 1000); 
} 
}); 

भागो यह:, तकनीकी रूप से और कलात्मक animated

संबंधित मुद्दे