চিত্রগুলিকে টুইটগুলিতে এনকোড করুন (চরম চিত্র সংক্ষেপণ সংস্করণ) [বন্ধ]


59

স্ট্যাক ওভারফ্লোতে খুব সফল টুইটার চিত্র এনকোডিং চ্যালেঞ্জের ভিত্তিতে ।

যদি কোনও চিত্রের মূল্য 1000 শব্দের হয় তবে আপনি 114.97 বাইটে কোনও চিত্রের কতটা ফিট করতে পারবেন?

আমি আপনাকে চ্যালেঞ্জ জানাই যে একটি সাধারণ-উদ্দেশ্য পদ্ধতি নিয়ে চিত্রগুলি একটি স্ট্যান্ডার্ড টুইটার মন্তব্যে সংকুচিত করতে কেবল প্রিন্টযোগ্য এএসসিআইআই পাঠ্য রয়েছে

নিয়মাবলী:

  1. আপনাকে অবশ্যই এমন একটি প্রোগ্রাম লিখতে হবে যা কোনও চিত্র নিতে এবং এনকোডযুক্ত পাঠ্য আউটপুট নিতে পারে।
  2. প্রোগ্রাম দ্বারা নির্মিত পাঠ্যটি অবশ্যই সর্বাধিক ১৪০ অক্ষর দীর্ঘ হতে হবে এবং কেবলমাত্র এমন অক্ষর থাকতে হবে যার কোড পয়েন্টগুলি অন্তর্ভুক্ত সহ 32-126 এর মধ্যে রয়েছে।
  3. আপনাকে অবশ্যই এমন একটি প্রোগ্রাম লিখতে হবে (সম্ভবত একই প্রোগ্রাম) যা এনকোডযুক্ত পাঠ্য নিতে এবং ফটোগ্রাফের একটি ডিকোড সংস্করণ আউটপুট নিতে পারে।
  4. আপনার প্রোগ্রামটি বাহ্যিক লাইব্রেরি এবং ফাইলগুলি ব্যবহার করতে পারে তবে ইন্টারনেট সংযোগ বা অন্যান্য কম্পিউটারের সাথে সংযোগের প্রয়োজন পড়তে পারে না।
  5. ডিকোডিং প্রক্রিয়াটি কোনওভাবেই মূল চিত্রগুলিতে অ্যাক্সেস বা ধারণ করতে পারে না।
  6. আপনার প্রোগ্রামকে অবশ্যই এই ফর্ম্যাটগুলির অন্তত একটিতে চিত্রগুলি গ্রহণ করতে হবে (অগত্যা আরও নয়): বিটম্যাপ, জেপিইজি, জিআইএফ, টিআইএফএফ, পিএনজি। যদি কিছু বা সমস্ত নমুনা চিত্রগুলি সঠিক ফর্ম্যাটে না থাকে তবে আপনি আপনার প্রোগ্রাম দ্বারা সংক্ষেপণের আগে সেগুলিকে নিজেকে রূপান্তর করতে পারেন।

বিচার করা যায়:

এটি কিছুটা বিষয়ভিত্তিক চ্যালেঞ্জ, সুতরাং বিজয়ীর (শেষ পর্যন্ত) আমার দ্বারা বিচার করা হবে। আমি আমার রায়কে কয়েকটি গুরুত্বপূর্ন কারণের উপর ফোকাস করব, যা নীচে হ্রাসযোগ্য গুরুত্বের সাথে তালিকাবদ্ধ:

  1. নমুনা চিত্র হিসাবে তালিকাভুক্ত নয় এমনগুলি সহ বিভিন্ন ধরণের চিত্র সংকোচনের যুক্তিসঙ্গত কাজ করার ক্ষমতা
  2. কোনও চিত্রের প্রধান উপাদানগুলির রূপরেখা সংরক্ষণের ক্ষমতা
  3. কোনও চিত্রের প্রধান উপাদানগুলির রঙগুলি সংকুচিত করার ক্ষমতা
  4. কোনও চিত্রের গৌণ বিবরণগুলির রূপরেখা এবং রঙগুলি সংরক্ষণ করার ক্ষমতা
  5. সংকোচনের সময়। যদিও কোনও চিত্র সঙ্কুচিত হওয়ার মতো গুরুত্বপূর্ণ নয়, তত দ্রুত প্রোগ্রামগুলি ধীরতর প্রোগ্রামগুলির চেয়ে ভাল যা একই কাজ করে।

আপনার জমা দেওয়ার ফলে ডিকম্প্রেশন পরবর্তী ফলাফলগুলি অন্তর্ভুক্ত করা উচিত, পাশাপাশি তৈরি হওয়া টুইটারের মন্তব্যও রয়েছে। যদি সম্ভব হয় তবে আপনি সোর্স কোডের একটি লিঙ্কও দিতে পারেন।

নমুনা চিত্র:

হিনডেনবার্গ , মাউন্টেনেন্স ল্যান্ডস্কেপ , মোনা লিসা , 2 ডি শেপস


U + 007F (127) এবং U + 0080 (128) নিয়ন্ত্রণের অক্ষর। আমি তাদের নিষিদ্ধ করার পরামর্শ দেব।
প্লিজস্ট্যান্ড

ভাল পর্যবেক্ষণ। আমি এটা ঠিক করব।
PhiNotPi

টুইটার কিছুটা হলেও ইউনিকোডকে অনুমতি দেয় না?
মেরিনাস

4
আমার মনে হচ্ছে আমি এর কোনও সমাধান পেটেন্ট করতে চাই।
শ্মিদ্দ্দী

2
"পর্বতমালা ল্যান্ডস্কেপ" 1024x768 - এটি শেষ হওয়ার আগে এটি পান! -> i.imgur.com/VaCzpRL.jpg <-
jdstankosky

উত্তর:


58

আমি প্রকৃত সংক্ষেপণ যোগ করে আমার পদ্ধতির উন্নতি করেছি। এটি এখন পুনরাবৃত্তভাবে নিম্নলিখিতগুলি সম্পাদন করে পরিচালনা করে:

  1. চিত্রটি YUV তে রূপান্তর করুন
  2. অ্যাসপেক্ট রেশিও সংরক্ষণ করে ইমেজটি ডাউনসাইজ করুন (যদি ছবিটি রঙ হয় তবে ক্রোমাটি লুমিন্যান্সের প্রস্থ এবং উচ্চতায় 1/3 অংশে নমুনা দেওয়া হয়)

  3. নমুনা হিসাবে বিট গভীরতা 4 বিট কমাতে

  4. নমুনা বিতরণ আরও অভিন্ন করে, চিত্রটিতে মধ্যমা পূর্বাভাস প্রয়োগ করুন

  5. চিত্রটিতে অভিযোজিত পরিসীমা সংক্ষেপণ প্রয়োগ করুন।

  6. সংক্ষিপ্ত চিত্রটির আকারটি <= 112 কিনা দেখুন

112 বাইটের সাথে খাপ খায় এমন বৃহত্তম চিত্রটি চূড়ান্ত চিত্র হিসাবে ব্যবহৃত হয়, বাকী দুটি বাইট সংক্ষেপিত চিত্রের প্রস্থ এবং উচ্চতা সংরক্ষণ করতে ব্যবহৃত হয়, এবং চিত্রটি রঙে আছে কিনা তা বোঝাচ্ছে একটি পতাকা। ডিকোডিংয়ের জন্য, প্রক্রিয়াটি বিপরীত হয় এবং চিত্রটি ছোট করে দেওয়া হয় যাতে ছোট মাত্রা 128 হয়।

উন্নতির জন্য কিছু জায়গা রয়েছে, যা সমস্ত উপলভ্য বাইটগুলি সাধারণত ব্যবহৃত হয় না, তবে আমি অনুভব করি যে আমি ডাউনস্যাম্পলিং + লসহীন সংকোচনের জন্য উল্লেখযোগ্যভাবে হ্রাসপ্রবণতার পর্যায়ে আছি।

দ্রুত এবং নোংরা সি ++ উত্স

উইন্ডোজ এক্স

মোনা লিসা (13x20 আলোকসজ্জা, 4x6 ক্রোমা)

&Jhmi8(,x6})Y"f!JC1jTzRh}$A7ca%/B~jZ?[_I17+91j;0q';|58yvX}YN426@"97W8qob?VB'_Ps`x%VR=H&3h8K=],4Bp=$K=#"v{thTV8^~lm vMVnTYT3rw N%I           

মোনালিসা মোনা লিসা টুইটার এনকোড করেছে

হিন্ডেনবার্গ (21x13 ঔজ্জ্বল্য)

GmL<B&ep^m40dPs%V[4&"~F[Yt-sNceB6L>Cs#/bv`\4{TB_P Rr7Pjdk7}<*<{2=gssBkR$>!['ROG6Xs{AEtnP=OWDP6&h{^l+LbLr4%R{15Zc<D?J6<'#E.(W*?"d9wdJ'       

হিন্ডেনবার্গ হিনডেনবুর্গ টুইটার এনকোড হয়েছে

পর্বতমালা (19x14 আলোকসজ্জা, 6x4 ক্রোমা)

Y\Twg]~KC((s_P>,*cePOTM_X7ZNMHhI,WeN(m>"dVT{+cXc?8n,&m$TUT&g9%fXjy"A-fvc 3Y#Yl-P![lk~;.uX?a,pcU(7j?=HW2%i6fo@Po DtT't'(a@b;sC7"/J           

পর্বত মাউন্টেন টুইটার এনকোডেড

2 ডি আকার (21x15 আলোকসজ্জা, 7x5 ক্রোমা)

n@|~c[#w<Fv8mD}2LL!g_(~CO&MG+u><-jT#{KXJy/``#S@m26CQ=[zejo,gFk0}A%i4kE]N ?R~^8!Ki*KM52u,M(his+BxqDCgU>ul*N9tNb\lfg}}n@HhX77S@TZf{k<CO69!    

2 ডি আকার 2D আকারের টুইটার এনকোড হয়েছে


7
এটি আমার অনুভব করে যে আমি ছানি বা অন্য কিছু বিকাশ করছি। হাহাহা, দুর্দান্ত কাজ!
jdstankosky

ভাল উন্নতি!
jdstankosky

37

প্রবেশপথ

চিত্রগুলি পুনরাবৃত্তভাবে অঞ্চলগুলিতে বিভক্ত করে কাজ করে। আমি উচ্চ তথ্যের সামগ্রী সহ অঞ্চলগুলিকে বিভক্ত করার চেষ্টা করি এবং দুটি অঞ্চলের মধ্যে রঙের পার্থক্য সর্বাধিকতর করতে বিভাজক রেখাটি বাছাই করি।

বিভাজন লাইনটি এনকোড করতে প্রতিটি বিভাজনকে কয়েকটি বিট ব্যবহার করে এনকোড করা হয়। প্রতিটি পাতার অঞ্চল একক রঙ হিসাবে এনকোড করা হয়।

এখানে চিত্র বর্ণনা লিখুন

4vN!IF$+fP0~\}:0d4a's%-~@[Q(qSd<<BDb}_s|qb&8Ys$U]t0mc]|! -FZO=PU=ln}TYLgh;{/"A6BIER|{lH1?ZW1VNwNL 6bOBFOm~P_pvhV)]&[p%GjJ ,+&!p"H4`Yae@:P

এখানে চিত্র বর্ণনা লিখুন

<uc}+jrsxi!_:GXM!'w5J)6]N)y5jy'9xBm8.A9LD/^]+t5#L-6?9 a=/f+-S*SZ^Ch07~s)P("(DAc+$[m-:^B{rQTa:/3`5Jy}AvH2p!4gYR>^sz*'U9(p.%Id9wf2Lc+u\&\5M>

এখানে চিত্র বর্ণনা লিখুন

lO6>v7z87n;XsmOW^3I-0'.M@J@CLL[4z-Xr:! VBjAT,##6[iSE.7+as8C.,7uleb=|y<t7sm$2z)k&dADF#uHXaZCLnhvLb.%+b(OyO$-2GuG~,y4NTWa=/LI3Q4w7%+Bm:!kpe&

এখানে চিত্র বর্ণনা লিখুন

ZoIMHa;v!]&j}wr@MGlX~F=(I[cs[N^M`=G=Avr*Z&Aq4V!c6>!m@~lJU:;cr"Xw!$OlzXD$Xi>_|*3t@qV?VR*It4gB;%>,e9W\1MeXy"wsA-V|rs$G4hY!G:%v?$uh-y~'Ltd.,(

হিনডেনবুর্গের ছবিটি দেখতে বেশ কৃপণ, তবে অন্যটি আমার পছন্দ।

package main

import (
    "os"
    "image"
    "image/color"
    "image/png"
    _ "image/jpeg"
    "math"
    "math/big"
)

// we have 919 bits to play with: floor(log_2(95^140))

// encode_region(r):
//   0
//      color of region (12 bits, 4 bits each color)
// or
//   1
//      dividing line through region
//        2 bits - one of 4 anchor points
//        4 bits - one of 16 angles
//      encode_region(r1)
//      encode_region(r2)
//
// start with single region
// pick leaf region with most contrast, split it

type Region struct {
    points []image.Point
    anchor int  // 0-3
    angle int // 0-15
    children [2]*Region
}

// mean color of region
func (region *Region) meanColor(img image.Image) (float64, float64, float64) {
    red := 0.0
    green := 0.0
    blue := 0.0
    num := 0
    for _, p := range region.points {
        r, g, b, _ := img.At(p.X, p.Y).RGBA()
        red += float64(r)
        green += float64(g)
        blue += float64(b)
        num++
    }
    return red/float64(num), green/float64(num), blue/float64(num)
}

// total non-uniformity in region's color
func (region *Region) deviation(img image.Image) float64 {
    mr, mg, mb := region.meanColor(img)
    d := 0.0
    for _, p := range region.points {
        r, g, b, _ := img.At(p.X, p.Y).RGBA()
        fr, fg, fb := float64(r), float64(g), float64(b)
        d += (fr - mr) * (fr - mr) + (fg - mg) * (fg - mg) + (fb - mb) * (fb - mb)
    }
    return d
}

// centroid of region
func (region *Region) centroid() (float64, float64) {
    cx := 0
    cy := 0
    num := 0
    for _, p := range region.points {
        cx += p.X
        cy += p.Y
        num++
    }
    return float64(cx)/float64(num), float64(cy)/float64(num)
}

// a few points in (or near) the region.
func (region *Region) anchors() [4][2]float64 {
    cx, cy := region.centroid()

    xweight := [4]int{1,1,3,3}
    yweight := [4]int{1,3,1,3}
    var result [4][2]float64
    for i := 0; i < 4; i++ {
        dx := 0
        dy := 0
        numx := 0
        numy := 0
        for _, p := range region.points {
            if float64(p.X) > cx {
                dx += xweight[i] * p.X
                numx += xweight[i]
            } else {
                dx += (4 - xweight[i]) * p.X
                numx += 4 - xweight[i]
            }
            if float64(p.Y) > cy {
                dy += yweight[i] * p.Y
                numy += yweight[i]
            } else {
                dy += (4 - yweight[i]) * p.Y
                numy += 4 - yweight[i]
            }
        }
        result[i][0] = float64(dx) / float64(numx)
        result[i][1] = float64(dy) / float64(numy)
    }
    return result
}

func (region *Region) split(img image.Image) (*Region, *Region) {
    anchors := region.anchors()
    // maximize the difference between the average color on the two sides
    maxdiff := 0.0
    var maxa *Region = nil
    var maxb *Region = nil
    maxanchor := 0
    maxangle := 0
    for anchor := 0; anchor < 4; anchor++ {
        for angle := 0; angle < 16; angle++ {
            sin, cos := math.Sincos(float64(angle) * math.Pi / 16.0)
            a := new(Region)
            b := new(Region)
            for _, p := range region.points {
                dx := float64(p.X) - anchors[anchor][0]
                dy := float64(p.Y) - anchors[anchor][1]
                if dx * sin + dy * cos >= 0 {
                    a.points = append(a.points, p)
                } else {
                    b.points = append(b.points, p)
                }
            }
            if len(a.points) == 0 || len(b.points) == 0 {
                continue
            }
            a_red, a_green, a_blue := a.meanColor(img)
            b_red, b_green, b_blue := b.meanColor(img)
            diff := math.Abs(a_red - b_red) + math.Abs(a_green - b_green) + math.Abs(a_blue - b_blue)
            if diff >= maxdiff {
                maxdiff = diff
                maxa = a
                maxb = b
                maxanchor = anchor
                maxangle = angle
            }
        }
    }
    region.anchor = maxanchor
    region.angle = maxangle
    region.children[0] = maxa
    region.children[1] = maxb
    return maxa, maxb
}

// split regions take 7 bits plus their descendents
// unsplit regions take 13 bits
// so each split saves 13-7=6 bits on the parent region
// and costs 2*13 = 26 bits on the children, for a net of 20 bits/split
func (region *Region) encode(img image.Image) []int {
    bits := make([]int, 0)
    if region.children[0] != nil {
        bits = append(bits, 1)
        d := region.anchor
        a := region.angle
        bits = append(bits, d&1, d>>1&1)
        bits = append(bits, a&1, a>>1&1, a>>2&1, a>>3&1)
        bits = append(bits, region.children[0].encode(img)...)
        bits = append(bits, region.children[1].encode(img)...)
    } else {
        bits = append(bits, 0)
        r, g, b := region.meanColor(img)
        kr := int(r/256./16.)
        kg := int(g/256./16.)
        kb := int(b/256./16.)
        bits = append(bits, kr&1, kr>>1&1, kr>>2&1, kr>>3)
        bits = append(bits, kg&1, kg>>1&1, kg>>2&1, kg>>3)
        bits = append(bits, kb&1, kb>>1&1, kb>>2&1, kb>>3)
    }
    return bits
}

func encode(name string) []byte {
    file, _ := os.Open(name)
    img, _, _ := image.Decode(file)

    // encoding bit stream
    bits := make([]int, 0)

    // start by encoding the bounds
    bounds := img.Bounds()
    w := bounds.Max.X - bounds.Min.X
    for ; w > 3; w >>= 1 {
        bits = append(bits, 1, w & 1)
    }
    bits = append(bits, 0, w & 1)
    h := bounds.Max.Y - bounds.Min.Y
    for ; h > 3; h >>= 1 {
        bits = append(bits, 1, h & 1)
    }
    bits = append(bits, 0, h & 1)

    // make new region containing whole image
    region := new(Region)
    region.children[0] = nil
    region.children[1] = nil
    for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
        for x := bounds.Min.X; x < bounds.Max.X; x++ {
            region.points = append(region.points, image.Point{x, y})
        }
    }

    // split the region with the most contrast until we're out of bits.
    regions := make([]*Region, 1)
    regions[0] = region
    for bitcnt := len(bits) + 13; bitcnt <= 919-20; bitcnt += 20 {
        var best_reg *Region
        best_dev := -1.0
        for _, reg := range regions {
            if reg.children[0] != nil {
                continue
            }
            dev := reg.deviation(img)
            if dev > best_dev {
                best_reg = reg
                best_dev = dev
            }
        }
        a, b := best_reg.split(img)
        regions = append(regions, a, b)
    }

    // encode regions
    bits = append(bits, region.encode(img)...)

    // convert to tweet
    n := big.NewInt(0)
    for i := 0; i < len(bits); i++ {
        n.SetBit(n, i, uint(bits[i]))
    }
    s := make([]byte,0)
    r := new(big.Int)
    for i := 0; i < 140; i++ {
        n.DivMod(n, big.NewInt(95), r)
        s = append(s, byte(r.Int64() + 32))
    }
    return s
}

// decodes and fills in region.  returns number of bits used.
func (region *Region) decode(bits []int, img *image.RGBA) int {
    if bits[0] == 1 {
        anchors := region.anchors()
        anchor := bits[1] + bits[2]*2
        angle := bits[3] + bits[4]*2 + bits[5]*4 + bits[6]*8
        sin, cos := math.Sincos(float64(angle) * math.Pi / 16.)
        a := new(Region)
        b := new(Region)
        for _, p := range region.points {
            dx := float64(p.X) - anchors[anchor][0]
            dy := float64(p.Y) - anchors[anchor][1]
            if dx * sin + dy * cos >= 0 {
                a.points = append(a.points, p)
            } else {
                b.points = append(b.points, p)
            }
        }
        x := a.decode(bits[7:], img)
        y := b.decode(bits[7+x:], img)
        return 7 + x + y
    }
    r := bits[1] + bits[2]*2 + bits[3]*4 + bits[4]*8
    g := bits[5] + bits[6]*2 + bits[7]*4 + bits[8]*8
    b := bits[9] + bits[10]*2 + bits[11]*4 + bits[12]*8
    c := color.RGBA{uint8(r*16+8), uint8(g*16+8), uint8(b*16+8), 255}
    for _, p := range region.points {
        img.Set(p.X, p.Y, c)
    }
    return 13
}

func decode(name string) image.Image {
    file, _ := os.Open(name)
    length, _ := file.Seek(0, 2)
    file.Seek(0, 0)
    tweet := make([]byte, length)
    file.Read(tweet)

    // convert to bit string
    n := big.NewInt(0)
    m := big.NewInt(1)
    for _, c := range tweet {
        v := big.NewInt(int64(c - 32))
        v.Mul(v, m)
        n.Add(n, v)
        m.Mul(m, big.NewInt(95))
    }
    bits := make([]int, 0)
    for ; n.Sign() != 0; {
        bits = append(bits, int(n.Int64() & 1))
        n.Rsh(n, 1)
    }
    for ; len(bits) < 919; {
        bits = append(bits, 0)
    }

    // extract width and height
    w := 0
    k := 1
    for ; bits[0] == 1; {
        w += k * bits[1]
        k <<= 1
        bits = bits[2:]
    }
    w += k * (2 + bits[1])
    bits = bits[2:]
    h := 0
    k = 1
    for ; bits[0] == 1; {
        h += k * bits[1]
        k <<= 1
        bits = bits[2:]
    }
    h += k * (2 + bits[1])
    bits = bits[2:]

    // make new region containing whole image
    region := new(Region)
    region.children[0] = nil
    region.children[1] = nil
    for y := 0; y < h; y++ {
        for x := 0; x < w; x++ {
            region.points = append(region.points, image.Point{x, y})
        }
    }

    // new image
    img := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{w, h}})

    // decode regions
    region.decode(bits, img)

    return img
}

func main() {
    if os.Args[1] == "encode" {
        s := encode(os.Args[2])
        file, _ := os.Create(os.Args[3])
        file.Write(s)
        file.Close()
    }
    if os.Args[1] == "decode" {
        img := decode(os.Args[2])
        file, _ := os.Create(os.Args[3])
        png.Encode(file, img)
        file.Close()
    }
}

3
বাবু, ওরা দেখতে সুন্দর লাগছে।
মিঃজান্ডার

2
ওগো গোশ যে দুর্দান্ত।
jdstankosky

4
অপেক্ষা করুন, আপনার স্ট্রিং কোথায়?
jdstankosky

1
এই পর্যন্ত আমার প্রিয়।
প্রিমো

4
কিউবিস্ট চেহারার জন্য +1 ।
ইলমারি করোনেন

36

পাইথন

এনকোডিংয়ের জন্য অলস , স্কাইপি এবং সাইকিট-চিত্র প্রয়োজন
ডিকোড শুধুমাত্র প্রয়োজন PIL

এটি সুপারপিক্সেল ইন্টারপোলেশন ভিত্তিক একটি পদ্ধতি। শুরু করতে, প্রতিটি চিত্র একই রঙের 70 টি একই আকারের অঞ্চলে বিভক্ত । উদাহরণস্বরূপ, ল্যান্ডস্কেপ চিত্র নিম্নলিখিত পদ্ধতিতে বিভক্ত:

এখানে চিত্র বর্ণনা লিখুন

প্রতিটি অঞ্চলের সেন্ট্রয়েড অবস্থিত (একটি গ্রিডের নিকটতম রাস্টার পয়েন্টে 402 পয়েন্টের বেশি নয়) পাশাপাশি এটির গড় রঙ (216 রঙের প্যালেট থেকে) এবং এই অঞ্চলগুলির প্রতিটি 0 থেকে একটি সংখ্যা হিসাবে এনকোড করা রয়েছে থেকে 86832 , করতে সক্ষম সঞ্চিত হচ্ছে 2.5 মুদ্রণযোগ্য ASCII অক্ষর (আসলে 2,497 , একটি greyscale বিট জন্য সঙ্কেতাক্ষরে লিখা যথেষ্ট রুম ছাড়ার)।

আপনি যদি মনোযোগী হন তবে আপনি লক্ষ্য করেছেন যে 140 / 2.5 = 56 টি অঞ্চল এবং আমি আগেই বলেছি 70 টি নয় । তবে লক্ষ্য করুন যে এই অঞ্চলগুলির প্রত্যেকটিই একটি অনন্য, তুলনামূলক অবজেক্ট, যা কোনও ক্রমে তালিকাভুক্ত হতে পারে। এই কারণে, আমরা ব্যবহার করতে পারি বিন্যাস প্রথম 56 অপরের জন্য সঙ্কেতাক্ষরে লিখা অঞ্চলে 14 কয়েক ওভার বাকি আকৃতি অনুপাত সঞ্চয় করতে বিট তার হিসাবে, পাশাপাশি।

আরও সুনির্দিষ্টভাবে, অতিরিক্ত 14 টি অঞ্চলের প্রত্যেকটি একটি সংখ্যায় রূপান্তরিত হয় এবং তারপরে এই সংখ্যাগুলির প্রত্যেকটি এক সাথে সংমিশ্রণ হয় (বর্তমান মান 86832 দ্বারা গুণিত করে এবং পরবর্তীটি যোগ করে)। এই (বিশাল) সংখ্যাটি পরে 56 টি বস্তুর ক্রম রূপান্তরিত হয় ।

উদাহরণ স্বরূপ:

from my_geom import *

# this can be any value from 0 to 56!, and it will map unambiguously to a permutation
num = 595132299344106583056657556772129922314933943196204990085065194829854239
perm = num2perm(num, 56)
print perm
print perm2num(perm)

আউটপুট হবে:

[0, 3, 33, 13, 26, 22, 54, 12, 53, 47, 8, 39, 19, 51, 18, 27, 1, 41, 50, 20, 5, 29, 46, 9, 42, 23, 4, 37, 21, 49, 2, 6, 55, 52, 36, 7, 43, 11, 30, 10, 34, 44, 24, 45, 32, 28, 17, 35, 15, 25, 48, 40, 38, 31, 16, 14]
595132299344106583056657556772129922314933943196204990085065194829854239

ফলস্বরূপ ফলাফলটি মূল 56 টি অঞ্চলে প্রয়োগ করা হয় । মূল সংখ্যা (এবং এইভাবে অতিরিক্ত 14 অঞ্চল) একইভাবে 56 টি এনকোডেড অঞ্চলগুলির ক্রমবিন্যাসকে এর সংখ্যাগত উপস্থাপনায় রূপান্তর করে তোলা যায়।

যখন --greyscaleবিকল্প এনকোডার সঙ্গে ব্যবহার করা হয়, 94 অঞ্চলে (পৃথক পরিবর্তে ব্যবহার করা হয় 70 , 24 সহ), 558 রাস্টার পয়েন্ট, এবং 16 ধূসর ছায়া গো।

ডিকোডিংয়ের সময়, এই অঞ্চলগুলির প্রত্যেককে উপরের দিক থেকে দেখা হিসাবে এই অঞ্চলের সেন্ট্রয়েডে এর ভার্টেক্স সহ অনন্ত প্রসারিত 3 ডি শঙ্কু হিসাবে বিবেচনা করা হয়। চূড়ান্ত পণ্যটি তৈরি করতে সীমানাগুলি এক সাথে মিশ্রিত করা হয়।

ভবিষ্যতের উন্নতি

  1. মোনা লিসার মাত্রা কিছুটা দূরে, যেভাবে আমি অনুপাতের অনুপাতটি সঞ্চয় করছি to আমার আলাদা সিস্টেম ব্যবহার করা দরকার। স্থির, ধরে নিলে যে মূল দিক অনুপাতটি কোথাও 1:21 এবং 21: 1 এর মধ্যে রয়েছে, যা আমি মনে করি যুক্তিসঙ্গত অনুমান।
  2. হিনডেনবার্গের অনেক উন্নতি হতে পারে। আমি যে রঙ প্যালেটটি ব্যবহার করছি তাতে কেবল ছয় ধূসর ছায়া রয়েছে। যদি আমি একটি গ্রেস্কেল-কেবল মোড প্রবর্তন করি তবে রঙের গভীরতা, অঞ্চলগুলির সংখ্যা, রাস্টার পয়েন্টের সংখ্যা বা তিনটির কোনও সংমিশ্রণ বাড়ানোর জন্য আমি অতিরিক্ত তথ্য ব্যবহার করতে পারি। আমি --greyscaleএনকোডারটিতে একটি বিকল্প যুক্ত করেছি , যা তিনটিই করে।
  3. 2 ডি আকারগুলি সম্ভবত মিশ্রণটি বন্ধ করে দেওয়া আরও ভাল দেখায়। আমি সম্ভবত এটির জন্য একটি পতাকা যুক্ত করব। বিভাগের অনুপাত নিয়ন্ত্রণ করার জন্য একটি এনকোডার বিকল্প এবং মিশ্রণটি বন্ধ করার জন্য একটি ডিকোডার বিকল্প যুক্ত করা হয়েছে।
  4. সংমিশ্রণকারীদের সাথে আরও মজা 56! 15 টি অতিরিক্ত অঞ্চল এবং 15 সংরক্ষণ করার জন্য এটি যথেষ্ট বড় large মোট 73 টির জন্য 2 টি আরও বেশি সঞ্চয় করতে যথেষ্ট । তবে অপেক্ষা করুন, আরও আছে! এই object৩ টি বস্তুর বিভাজনটি আরও তথ্য সংরক্ষণ করতে ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, আছে 73 56 চয়ন প্রাথমিক নির্বাচন করতে উপায়ে 56 অঞ্চলে, এবং তারপর 17 15 চয়ন পরবর্তী নির্বাচন করার উপায় 15 । মোট 2403922132944423030 বিভাজন, মোট 76 টির জন্য 3 টি আরও অঞ্চল সংরক্ষণের জন্য যথেষ্ট বড়। আমি স্বতন্ত্র সংখ্যা সব পার্টিশন একটি চতুর উপায় সঙ্গে আসা পর্যন্ত প্রয়োজন চাই 73 এর দলে 56 , 15 , 2 ... এবং ফিরে । সম্ভবত ব্যবহারিক নয়, তবে ভাবতে আগ্রহী একটি সমস্যা।

0VW*`Gnyq;c1JBY}tj#rOcKm)v_Ac\S.r[>,Xd_(qT6 >]!xOfU9~0jmIMG{hcg-'*a.s<X]6*%U5>/FOze?cPv@hI)PjpK9\iA7P ]a-7eC&ttS[]K>NwN-^$T1E.1OH^c0^"J 4V9X

এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন


0Jc?NsbD#1WDuqT]AJFELu<!iE3d!BB>jOA'L|<j!lCWXkr:gCXuD=D\BL{gA\ 8#*RKQ*tv\\3V0j;_4|o7>{Xage-N85):Q/Hl4.t&'0pp)d|Ry+?|xrA6u&2E!Ls]i]T<~)58%RiA

এবং

4PV 9G7X|}>pC[Czd!5&rA5 Eo1Q\+m5t:r#;H65NIggfkw'h4*gs.:~<bt'VuVL7V8Ed5{`ft7e>HMHrVVUXc.{#7A|#PBm,i>1B781.K8>s(yUV?a<*!mC@9p+Rgd<twZ.wuFnN dp

এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

দ্বিতীয়টি --greyscaleবিকল্পটির সাথে এনকোড হয়েছে ।


3dVY3TY?9g+b7!5n`)l"Fg H$ 8n?[Q-4HE3.c:[pBBaH`5'MotAj%a4rIodYO.lp$h a94$n!M+Y?(eAR,@Y*LiKnz%s0rFpgnWy%!zV)?SuATmc~-ZQardp=?D5FWx;v=VA+]EJ(:%

এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

--greyscaleবিকল্পের সাথে এনকোড করা হয়েছে ।


.9l% Ge<'_)3(`DTsH^eLn|l3.D_na,,sfcpnp{"|lSv<>}3b})%m2M)Ld{YUmf<Uill,*:QNGk,'f2; !2i88T:Yjqa8\Ktz4i@h2kHeC|9,P` v7Xzd Yp&z:'iLra&X&-b(g6vMq

এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

এনকোডযুক্ত --ratio 60এবং --no-blendingবিকল্পগুলির সাথে ডিকোড করা হয়েছে ।


encoder.py

from __future__ import division
import argparse, numpy
from skimage.io import imread
from skimage.transform import resize
from skimage.segmentation import slic
from skimage.measure import regionprops
from my_geom import *

def encode(filename, seg_ratio, greyscale):
  img = imread(filename)

  height = len(img)
  width = len(img[0])
  ratio = width/height

  if greyscale:
    raster_size = 558
    raster_ratio = 11
    num_segs = 94
    set1_len = 70
    max_num = 8928  # 558 * 16
  else:
    raster_size = 402
    raster_ratio = 13
    num_segs = 70
    set1_len = 56
    max_num = 86832 # 402 * 216

  raster_width = (raster_size*ratio)**0.5
  raster_height = int(raster_width/ratio)
  raster_width = int(raster_width)

  resize_height = raster_height * raster_ratio
  resize_width = raster_width * raster_ratio

  img = resize(img, (resize_height, resize_width))

  segs = slic(img, n_segments=num_segs-4, ratio=seg_ratio).astype('int16')

  max_label = segs.max()
  numpy.place(segs, segs==0, [max_label+1])
  regions = [None]*(max_label+2)

  for props in regionprops(segs):
    label = props['Label']
    props['Greyscale'] = greyscale
    regions[label] = Region(props)

  for i, a in enumerate(regions):
    for j, b in enumerate(regions):
      if a==None or b==None or a==b: continue
      if a.centroid == b.centroid:
        numpy.place(segs, segs==j, [i])
        regions[j] = None

  for y in range(resize_height):
    for x in range(resize_width):
      label = segs[y][x]
      regions[label].add_point(img[y][x])

  regions = [r for r in regions if r != None]

  if len(regions)>num_segs:
    regions = sorted(regions, key=lambda r: r.area)[-num_segs:]

  regions = sorted(regions, key=lambda r: r.to_num(raster_width))

  set1, set2 = regions[-set1_len:], regions[:-set1_len]

  set2_num = 0
  for s in set2:
    set2_num *= max_num
    set2_num += s.to_num(raster_width)

  set2_num = ((set2_num*85 + raster_width)*85 + raster_height)*25 + len(set2)
  perm = num2perm(set2_num, set1_len)
  set1 = permute(set1, perm)

  outnum = 0
  for r in set1:
    outnum *= max_num
    outnum += r.to_num(raster_width)

  outnum *= 2
  outnum += greyscale

  outstr = ''
  for i in range(140):
    outstr = chr(32 + outnum%95) + outstr
    outnum //= 95

  print outstr

parser = argparse.ArgumentParser(description='Encodes an image into a tweetable format.')
parser.add_argument('filename', type=str,
  help='The filename of the image to encode.')
parser.add_argument('--ratio', dest='seg_ratio', type=float, default=30,
  help='The segmentation ratio. Higher values (50+) will result in more regular shapes, lower values in more regular region color.')
parser.add_argument('--greyscale', dest='greyscale', action='store_true',
  help='Encode the image as greyscale.')
args = parser.parse_args()

encode(args.filename, args.seg_ratio, args.greyscale)

decoder.py

from __future__ import division
import argparse
from PIL import Image, ImageDraw, ImageChops, ImageFilter
from my_geom import *

def decode(instr, no_blending=False):
  innum = 0
  for c in instr:
    innum *= 95
    innum += ord(c) - 32

  greyscale = innum%2
  innum //= 2

  if greyscale:
    max_num = 8928
    set1_len = 70
    image_mode = 'L'
    default_color = 0
    raster_ratio = 11
  else:
    max_num = 86832
    set1_len = 56
    image_mode = 'RGB'
    default_color = (0, 0, 0)
    raster_ratio = 13

  nums = []
  for i in range(set1_len):
    nums = [innum%max_num] + nums
    innum //= max_num

  set2_num = perm2num(nums)

  set2_len = set2_num%25
  set2_num //= 25

  raster_height = set2_num%85
  set2_num //= 85
  raster_width = set2_num%85
  set2_num //= 85

  resize_width = raster_width*raster_ratio
  resize_height = raster_height*raster_ratio

  for i in range(set2_len):
    nums += set2_num%max_num,
    set2_num //= max_num

  regions = []
  for num in nums:
    r = Region()
    r.from_num(num, raster_width, greyscale)
    regions += r,

  masks = []

  outimage = Image.new(image_mode, (resize_width, resize_height), default_color)

  for a in regions:
    mask = Image.new('L', (resize_width, resize_height), 255)
    for b in regions:
      if a==b: continue
      submask = Image.new('L', (resize_width, resize_height), 0)
      poly = a.centroid.bisected_poly(b.centroid, resize_width, resize_height)
      ImageDraw.Draw(submask).polygon(poly, fill=255, outline=255)
      mask = ImageChops.multiply(mask, submask)
    outimage.paste(a.avg_color, mask=mask)

  if not no_blending:
    outimage = outimage.resize((raster_width, raster_height), Image.ANTIALIAS)
    outimage = outimage.resize((resize_width, resize_height), Image.BICUBIC)
    smooth = ImageFilter.Kernel((3,3),(1,2,1,2,4,2,1,2,1))
    for i in range(20):outimage = outimage.filter(smooth)
  outimage.show()

parser = argparse.ArgumentParser(description='Decodes a tweet into and image.')
parser.add_argument('--no-blending', dest='no_blending', action='store_true',
    help="Do not blend the borders in the final image.")
args = parser.parse_args()

instr = raw_input()
decode(instr, args.no_blending)

my_geom.py

from __future__ import division

class Point:
  def __init__(self, x, y):
    self.x = x
    self.y = y
    self.xy = (x, y)

  def __eq__(self, other):
    return self.x == other.x and self.y == other.y

  def __lt__(self, other):
    return self.y < other.y or (self.y == other.y and self.x < other.x)

  def inv_slope(self, other):
    return (other.x - self.x)/(self.y - other.y)

  def midpoint(self, other):
    return Point((self.x + other.x)/2, (self.y + other.y)/2)

  def dist2(self, other):
    dx = self.x - other.x
    dy = self.y - other.y
    return dx*dx + dy*dy

  def bisected_poly(self, other, resize_width, resize_height):
    midpoint = self.midpoint(other)
    points = []
    if self.y == other.y:
      points += (midpoint.x, 0), (midpoint.x, resize_height)
      if self.x < midpoint.x:
        points += (0, resize_height), (0, 0)
      else:
        points += (resize_width, resize_height), (resize_width, 0)
      return points
    elif self.x == other.x:
      points += (0, midpoint.y), (resize_width, midpoint.y)
      if self.y < midpoint.y:
        points += (resize_width, 0), (0, 0)
      else:
        points += (resize_width, resize_height), (0, resize_height)
      return points
    slope = self.inv_slope(other)
    y_intercept = midpoint.y - slope*midpoint.x
    if self.y > midpoint.y:
      points += ((resize_height - y_intercept)/slope, resize_height),
      if slope < 0:
        points += (resize_width, slope*resize_width + y_intercept), (resize_width, resize_height)
      else:
        points += (0, y_intercept), (0, resize_height)
    else:
      points += (-y_intercept/slope, 0),
      if slope < 0:
        points += (0, y_intercept), (0, 0)
      else:
        points += (resize_width, slope*resize_width + y_intercept), (resize_width, 0)
    return points

class Region:
  def __init__(self, props={}):
    if props:
      self.greyscale = props['Greyscale']
      self.area = props['Area']
      cy, cx = props['Centroid']
      if self.greyscale:
        self.centroid = Point(int(cx/11)*11+5, int(cy/11)*11+5)
      else:
        self.centroid = Point(int(cx/13)*13+6, int(cy/13)*13+6)
    self.num_pixels = 0
    self.r_total = 0
    self.g_total = 0
    self.b_total = 0

  def __lt__(self, other):
    return self.centroid < other.centroid

  def add_point(self, rgb):
    r, g, b = rgb
    self.r_total += r
    self.g_total += g
    self.b_total += b
    self.num_pixels += 1
    if self.greyscale:
      self.avg_color = int((3.2*self.r_total + 10.7*self.g_total + 1.1*self.b_total)/self.num_pixels + 0.5)*17
    else:
      self.avg_color = (
        int(5*self.r_total/self.num_pixels + 0.5)*51,
        int(5*self.g_total/self.num_pixels + 0.5)*51,
        int(5*self.b_total/self.num_pixels + 0.5)*51)

  def to_num(self, raster_width):
    if self.greyscale:
      raster_x = int((self.centroid.x - 5)/11)
      raster_y = int((self.centroid.y - 5)/11)
      return (raster_y*raster_width + raster_x)*16 + self.avg_color//17
    else:
      r, g, b = self.avg_color
      r //= 51
      g //= 51
      b //= 51
      raster_x = int((self.centroid.x - 6)/13)
      raster_y = int((self.centroid.y - 6)/13)
      return (raster_y*raster_width + raster_x)*216 + r*36 + g*6 + b

  def from_num(self, num, raster_width, greyscale):
    self.greyscale = greyscale
    if greyscale:
      self.avg_color = num%16*17
      num //= 16
      raster_x, raster_y = num%raster_width, num//raster_width
      self.centroid = Point(raster_x*11 + 5, raster_y*11+5)
    else:
      rgb = num%216
      r, g, b = rgb//36, rgb//6%6, rgb%6
      self.avg_color = (r*51, g*51, b*51)
      num //= 216
      raster_x, raster_y = num%raster_width, num//raster_width
      self.centroid = Point(raster_x*13 + 6, raster_y*13 + 6)

def perm2num(perm):
  num = 0
  size = len(perm)
  for i in range(size):
    num *= size-i
    for j in range(i, size): num += perm[j]<perm[i]
  return num

def num2perm(num, size):
  perm = [0]*size
  for i in range(size-1, -1, -1):
    perm[i] = int(num%(size-i))
    num //= size-i
    for j in range(i+1, size): perm[j] += perm[j] >= perm[i]
  return perm

def permute(arr, perm):
  size = len(arr)
  out = [0] * size
  for i in range(size):
    val = perm[i]
    out[i] = arr[val]
  return out


মোনা লিসার রঙিন সংস্করণ দেখে মনে হচ্ছে তার কোনও একটি বুকে পপ করা হয়েছে। একপাশে ঠাট্টা করা, এটি অবিশ্বাস্য।
jdstankosky

4
অতিরিক্ত ডেটা এনকোড করার জন্য অনুমতিগুলি ব্যবহার করা বরং চালাক।
স্যার_লগসালোট

সত্যিই দুর্দান্ত। আপনি এই 3 টি ফাইল দিয়ে একটি টুকরো টানতে পারেন? gist.github.com
রুবিক

2
@ রবিক এটি অবিশ্বাস্যরূপে ক্ষতির কারণ, এই চ্যালেঞ্জের সমস্ত সমাধান যেমন রয়েছে;)
প্রিমো ২

17

পিএইচপি

ঠিক আছে, আমাকে কিছুক্ষণ সময় লাগল, কিন্তু এখানে। গ্রেস্কেল সমস্ত চিত্র। রঙগুলি আমার পদ্ধতির জন্য এনকোড করতে অনেকগুলি বিট নিয়েছিল: পি


মোনা লিসা
47 রঙের একরঙা
101 বাইট স্ট্রিং।

dt99vvv9t8G22+2eZbbf55v3+fAH9X+AD/0BAF6gIOX5QRy7xX8em9/UBAEVXKiiqKqqqiqqqqNqqqivtXqqMAFVUBVVVVVVVVVVU

মোনা Lisa


2 ডি আকার
36 রঙের একরঙা
105 বাইট স্ট্রিং।

oAAAAAAABMIDUAAEBAyoAAAAAgAwAAAAADYBtsAAAJIDbYAAAAA22AGwAAAAAGwAAAAAAAAAAKgAAAAAqgAAAACoAAAAAAAAAAAAAAAAA

2d 2dc


হিনডেনবুর্গ
62 টি রঙের একরঙা
112 টি অক্ষর।

t///tCSuvv/99tmwBI3/21U5gCW/+2bdDMxLf+r6VsaHb/tt7TAodv+NhtbFVX/bGD1IVq/4MAHbKq/4AABbVX/AQAFN1f8BCBFntb/6ttYdWnfg

ছবি এখানে এখানে চিত্র বর্ণনা লিখুন


পর্বতমালা
63 Col টি রঙের একরঙা
122 টি অক্ষর।

qAE3VTkaIAKgqSFigAKoABgQEqAABuAgUQAGenRIBoUh2eqhABCee/2qSSAQntt/s2kJCQbf/bbaJgbWebzqsPZ7bZttwABTc3VAUFDbKqqpzY5uqpudnp5vZg

picshere এখানে চিত্র বর্ণনা লিখুন


আমার পদ্ধতি

আমি আমার বিটস্ট্রিমটি একধরণের বেস 64 এর সাথে এনকোড করেছি with এটি পাঠযোগ্য পাঠ্যে এনকোড করার আগে যা ঘটেছিল তা এখানে।

আমি উত্স চিত্রটি লোড করেছি এবং এটিকে 20 পিক্সেলের সর্বোচ্চ উচ্চতা বা প্রস্থে (ওরিয়েন্টেশন, প্রতিকৃতি / ল্যান্ডস্কেপের উপর নির্ভর করে) আকার দেব।

এরপরে আমি নতুন চিত্রটির প্রতিটি পিক্সেলটি 6 রঙের গ্রেস্কেল প্যালেটের নিকটতম ম্যাচের সাথে পুনরায় রঙ করলাম।

এটি সম্পন্ন হওয়ার পরে, আমি প্রতিটি পিক্সেল বর্ণগুলি [এএফ] দ্বারা প্রতিনিধিত্ব করে একটি স্ট্রিং তৈরি করি।

আমি তারপরে স্ট্রিংয়ের মধ্যে 6 টি বিভিন্ন বর্ণের বিতরণ গণনা করি এবং বর্ণের ফ্রিকোয়েন্সিগুলির উপর ভিত্তি করে এনকোডিংয়ের জন্য সর্বাধিক অনুকূলিত বাইনারি গাছ নির্বাচন করি। 15 টি বাইনারি গাছ রয়েছে।

[1|0]চিত্রটি লম্বা বা প্রশস্ত কিনা তার উপর নির্ভর করে আমি আমার বিট স্ট্রিমটি একক বিট দিয়ে শুরু করি । আমি তারপরে স্ট্রিমের পরবর্তী 4 টি বিট ব্যবহার করি ডিকোডারকে জানাতে যে বাইনারি গাছটি চিত্রটি ডিকোড করতে ব্যবহার করা উচিত inform

নীচেরটি হ'ল চিত্রটির প্রতিনিধিত্বকারী বিটের প্রবাহ। প্রতিটি পিক্সেল এবং এর রঙ 2 বা 3 বিট দ্বারা প্রতিনিধিত্ব করা হয়। এটি আমাকে প্রতিটি মুদ্রিত আসকি চরিত্রের জন্য কমপক্ষে 2 এবং 3 পিক্সেল পর্যন্ত মূল্যবান তথ্য সঞ্চয় করতে দেয়। এখানে বাইনারি গাছের একটি নমুনা দেওয়া হয়েছে 1110, যা মোনালিসা ব্যবহার করেছেন:

    TREE
   /    \
  #      #
 / \    / \
E   #  F   #
   / \    / \
  A   B  C   D

E 00এবং F বর্ণগুলি 10মোনা লিসার সর্বাধিক সাধারণ রঙ। এ 010, বি 011, সি 110এবং ডি 111সবচেয়ে কম ঘন ঘন হয়।

বাইনারি গাছগুলি এ জাতীয়ভাবে কাজ করে: কিছুটা বিট থেকে কিছুটা যাওয়ার 0অর্থ বাম দিকে চলে 1যাওয়া মানে ডানদিকে। যতক্ষণ না আপনি গাছের কোনও পাতা বা একটি শেষ প্রান্তে আঘাত করেন। আপনি যে পাতাটি শেষ করেন তা হ'ল আপনি চান এমন চরিত্র।

যাইহোক, আমি বাইনারি স্টিংকে বেস 64 অক্ষরে এনকোড করেছি। স্ট্রিংটি ডিকোড করার সময়, প্রক্রিয়াটি বিপরীতভাবে সম্পন্ন হয়, সমস্ত পিক্সেল যথাযথ রঙে বরাদ্দ করা হয় এবং তারপরে চিত্রটি এনকোড আকারের দ্বিগুণ করে মাপানো হয় (সর্বোচ্চ 40 পিক্সেল হয় এক্স বা ওয়াই, যেটি বৃহত্তর হয়) এবং তারপরে একটি কনভলিউশন ম্যাট্রিক্স হয় রঙগুলি মসৃণ করতে পুরো জিনিসটিতে প্রয়োগ।

যাইহোক, এখানে বর্তমান কোড: " পেস্টবিন লিঙ্ক "

এটি কুৎসিত, তবে আপনি যদি উন্নতির কোনও ঘর দেখতে পান তবে আমাকে জানান। আমি যেমন চাই তেমন একসাথে হ্যাক করেছি। আমি শিখেছি একটি অনেক এই প্রতিদ্বন্দ্বিতা থেকে। ওপিকে ধন্যবাদ পোস্ট করার জন্য!


2
আপনার কাছে কতটি অব্যবহৃত স্টোরেজ স্পেস রয়েছে তা বিবেচনা করে এগুলি অবিশ্বাস্যভাবে দুর্দান্ত দেখাচ্ছে (মোনা লিসা 920 উপলব্ধ থেকে কেবল 606 বিট ব্যবহার করে!)।
primo

ধন্যবাদ, প্রিমো, আমি সত্যিই এটির প্রশংসা করি। আমি সবসময় আপনার কাজের প্রশংসা করি, তাই আপনি শুনে শুনে তা বেশ চাটুকার!
jdstankosky

13

আমার প্রথম প্রচেষ্টা। এটি উন্নতির জন্য জায়গা আছে। আমি মনে করি যে ফর্ম্যাটটি নিজেই কাজ করে, সমস্যাটি এনকোডারে। এটি, এবং আমি আমার আউটপুট থেকে পৃথক বিটগুলি মিস করছি ... আমার (তখন কিছুটা উচ্চতর মানের এখানে) ফাইলটি 144 টি অক্ষরে শেষ হয়েছিল, যখন কিছু বাকী থাকা উচিত ছিল। (এবং আমি সত্যিই এখানে থাকতে চাই - এইগুলির মধ্যে পার্থক্যগুলি লক্ষণীয়) যদিও আমি শিখেছি, কখনই বড় আকারের 140 চরিত্রটিকে বড় করে দেখবেন না ...

আমি এটিকে আরআইএসসি-ওএস প্যালেটের পরিবর্তিত সংস্করণে নামিয়ে আনি - মূলত, কারণ আমার 32 টি রঙিন প্যালেট দরকার ছিল এবং এটি শুরু করার মতো ভাল জায়গা বলে মনে হয়েছিল। এটি কিছু পরিবর্তন করার সাথেও করতে পারে বলে আমি মনে করি। প্যালেট

আমি এটিকে নীচের আকারগুলিতে আকার বিভক্ত করছি : এবং চিত্রটিকে প্যালেট ব্লকে (এই ক্ষেত্রে 2x2 পিক্সেল) সামনের এবং পিছনের বর্ণের মধ্যে বিভক্ত করুন।

ফলাফল:

টুইটগুলি, আসলগুলি এবং কীভাবে টুইটটি ডিকোড করা হয় তা নীচে রয়েছে

*=If`$aX:=|"&brQ(EPZwxu4H";|-^;lhJCfQ(W!TqWTai),Qbd7CCtmoc(-hXt]/l87HQyaYTEZp{eI`/CtkHjkFh,HJWw%5[d}VhHAWR(@;M's$VDz]17E@6

Hindeberg আমার হিনডেনবার্গ

"&7tpnqK%D5kr^u9B]^3?`%;@siWp-L@1g3p^*kQ=5a0tBsA':C0"*QHVDc=Z='Gc[gOpVcOj;_%>.aeg+JL4j-u[a$WWD^)\tEQUhR]HVD5_-e`TobI@T0dv_el\H1<1xw[|D

পর্বত আমার পর্বত

)ey`ymlgre[rzzfi"K>#^=z_Wi|@FWbo#V5|@F)uiH?plkRS#-5:Yi-9)S3:#3 Pa4*lf TBd@zxa0g;li<O1XJ)YTT77T1Dg1?[w;X"U}YnQE(NAMQa2QhTMYh..>90DpnYd]?

আকার আমার আকার

%\MaaX/VJNZX=Tq,M>2"AwQVR{(Xe L!zb6(EnPuEzB}Nk:U+LAB_-K6pYlue"5*q>yDFw)gSC*&,dA98`]$2{&;)[ 4pkX |M _B4t`pFQT8P&{InEh>JHYn*+._[b^s754K_

মোনালিসা মোনা লিসা মাইন

আমি জানি রঙগুলি ভুল, তবে আমি আসলে মোনালিসা পছন্দ করি। যদি আমি অস্পষ্টতা অপসারণ করি (যা খুব বেশি শক্ত হবে না), এটি একটি যুক্তিসঙ্গত কিউবিস্টের ধারণা: পি

আমার কাজ করা উচিত

  • আকৃতি সনাক্তকরণ যুক্ত করা হচ্ছে
  • একটি ভাল রঙ "পার্থক্য" অ্যালগরিদম
  • আমার অনুপস্থিত বিটগুলি কোথায় গেছে তা নির্ধারণ করে

সেগুলি ঠিক করার চেষ্টা করার পরে এটিকে আরও কিছু কাজ দেব এবং এনকোডারটি উন্নত করব। অতিরিক্ত 20 বা ততোধিক অক্ষরগুলি প্রচুর পরিমাণে পার্থক্য করে। আমি তাদের ফিরে চাই।

সি # উত্স এবং রঙ প্যালেটটি https://dl.rodboxusercontent.com/u/46145976/Base96.zip এ রয়েছে - যদিও, পশ্চাত্পদৃষ্টিতে, পৃথকভাবে চালানোর সময় পুরোপুরি কাজ করতে পারে না (প্রোগ্রামগুলিতে যুক্তিগুলির ফাঁকা স্থানগুলি না যায় তাই) ভাল)।

আমার মোটামুটি গড় মেশিনে কয়েক সেকেন্ড পরে এনকোডার কম লাগে।


11
শহরবাসী. আমি গ্যালারিতে যে সমসাময়িক শিল্প দেখেছি তার চেয়ে সেগুলি দেখতে আরও ভাল দেখাচ্ছে ... আপনার উচিত তাদের বিশাল প্রিন্টগুলি তৈরি করা এবং সেগুলি বিক্রি করা!
jdstankosky

1
দেখে মনে হচ্ছে আমার আটারি থেকে কার্টিজ নিতে হবে এবং এটিকে আবার প্লাগ ইন করতে হবে I আমি এটি পছন্দ করি।
আন্ডারগ্রাউন্ডোমোনাইল

13

আমি রঙটি রাখার চেষ্টা ছেড়ে দিয়ে কালো এবং সাদা হয়ে গেলাম, যেহেতু আমি রঙের সাথে চেষ্টা করেছিলাম তা সমস্তই অজ্ঞাতনীয়।

মূলত এটি যা করে তা হ'ল পিক্সেলগুলি প্রায় 3 টি সমান অংশে ভাগ করা: কালো, ধূসর এবং সাদা। এটি আকারও রাখে না।

হিন্ডেনবার্গ

~62RW.\7`?a9}A.jvCedPW0t)]g/e4 |+D%n9t^t>wO><",C''!!Oh!HQq:WF>\uEG?E=Mkj|!u}TC{7C7xU:bb`We;3T/2:Zw90["$R25uh0732USbz>Q;q"

হিন্ডেনবার্গ HindenburgCompressed

মোনালিসা

=lyZ(i>P/z8]Wmfu>] T55vZB:/>xMz#Jqs6U3z,)n|VJw<{Mu2D{!uyl)b7B6x&I"G0Y<wdD/K4hfrd62_8C\W7ArNi6R\Xz%f U[);YTZFliUEu{m%[gw10rNY_`ICNN?_IB/C&=T

মোনালিসা MonaLisaCompressed

পর্বতমালা

+L5#~i%X1aE?ugVCulSf*%-sgIg8hQ3j/df=xZv2v?'XoNdq=sb7e '=LWm\E$y?=:"#l7/P,H__W/v]@pwH#jI?sx|n@h\L %y(|Ry.+CvlN $Kf`5W(01l2j/sdEjc)J;Peopo)HJ

পর্বতমালা MountainsCompressed

আকার

3A"3yD4gpFtPeIImZ$g&2rsdQmj]}gEQM;e.ckbVtKE(U$r?{,S>tW5JzQZDzoTy^mc+bUV vTUG8GXs{HX'wYR[Af{1gKwY|BD]V1Z'J+76^H<K3Db>Ni/D}][n#uwll[s'c:bR56:

আকার ShapesCompressed

এখানে প্রোগ্রাম। python compress.py -c img.pngসংকোচনের img.pngএবং টুইট মুদ্রণ।

python compress.py -d img.pngস্টিডিনের কাছ থেকে টুইট নেয় এবং চিত্রটি সংরক্ষণ করে img.png

from PIL import Image
import sys
quanta  = 3
width   = 24
height  = 24

def compress(img):
    pix = img.load()
    psums = [0]*(256*3)
    for x in range(width):
        for y in range(height):
            r,g,b,a = pix[x,y]
            psums[r+g+b] += 1
    s = 0
    for i in range(256*3):
        s = psums[i] = psums[i]+s

    i = 0
    for x in range(width):
        for y in range(height):
            r,g,b,a = pix[x,y]
            t = psums[r+g+b]*quanta / (width*height)
            if t == quanta:
                t -= 1
            i *= quanta
            i += t
    s = []
    while i:
        s += chr(i%95 + 32)
        i /= 95
    return ''.join(s)

def decompress(s):
    i = 0
    for c in s[::-1]:
        i *= 95
        i += ord(c) - 32
    img = Image.new('RGB',(width,height))
    pix = img.load()
    for x in range(width)[::-1]:
        for y in range(height)[::-1]:
            t = i % quanta
            i /= quanta
            t *= 255/(quanta-1)
            pix[x,y] = (t,t,t)
    return img

if sys.argv[1] == '-c':
    img = Image.open(sys.argv[2]).resize((width,height))
    print compress(img)
elif sys.argv[1] == '-d':
    img = decompress(raw_input())
    img.resize((256,256)).save(sys.argv[2],'PNG')

লোল, অ-সীমাবদ্ধ দিক অনুপাতের জন্য +1।
jdstankosky

7

আর-তে আমার বিনয়ী অবদান:

encoder<-function(img_file){
    img0 <- as.raster(png::readPNG(img_file))
    d0 <- dim(img0)
    r <- d0[1]/d0[2]
    f <- floor(sqrt(140/r))
    d1 <- c(floor(f*r),f)
    dx <- floor(d0[2]/d1[2])
    dy <- floor(d0[1]/d1[1])
    img1 <- matrix("",ncol=d1[2],nrow=d1[1])
    x<-seq(1,d0[1],by=dy)
    y<-seq(1,d0[2],by=dx)
    for(i in seq_len(d1[1])){
        for (j in seq_len(d1[2])){
            img1[i,j]<-names(which.max(table(img0[x[i]:(x[i]+dy-1),y[j]:(y[j]+dx-1)])))
            }
        }
    img2 <- as.vector(img1)
    table1 <- array(sapply(seq(0,255,length=4),function(x)sapply(seq(0,255,length=4),function(y)sapply(seq(0,255,length=4),function(z)rgb(x/255,y/255,z/255)))),dim=c(4,4,4))
    table2 <- array(strsplit(rawToChar(as.raw(48:(48+63))),"")[[1]],dim=c(4,4,4))
    table3 <- cbind(1:95,sapply(32:126,function(x)rawToChar(as.raw(x))))
    a <- as.array(cut(colorspace::hex2RGB(img2)@coords,breaks=seq(0,1,length=5),include.lowest=TRUE))
    dim(a) <- c(length(img2),3)
    img3 <- apply(a,1,function(x)paste("#",c("00","55","AA","FF")[x[1]],c("00","55","AA","FF")[x[2]],c("00","55","AA","FF")[x[3]],sep=""))
    res<-paste(sapply(img3,function(x)table2[table1==x]),sep="",collapse="")
    paste(table3[table3[,1]==d1[1],2],table3[table3[,1]==d1[2],2],res,collapse="",sep="")
    }

decoder<-function(string){
    s <- unlist(strsplit(string,""))
    table1 <- array(sapply(seq(0,255,length=4),function(x)sapply(seq(0,255,length=4),function(y)sapply(seq(0,255,length=4),function(z)rgb(x/255,y/255,z/255)))),dim=c(4,4,4))
    table2 <- array(strsplit(rawToChar(as.raw(48:(48+63))),"")[[1]],dim=c(4,4,4))
    table3 <- cbind(1:95,sapply(32:126,function(x)rawToChar(as.raw(x))))
    nr<-as.integer(table3[table3[,2]==s[1],1])
    nc<-as.integer(table3[table3[,2]==s[2],1])
    img <- sapply(s[3:length(s)],function(x){table1[table2==x]})
    png(w=nc,h=nr,u="in",res=100)
    par(mar=rep(0,4))
    plot(c(1,nr),c(1,nc),type="n",axes=F,xaxs="i",yaxs="i")
    rasterImage(as.raster(matrix(img,nr,nc)),1,1,nr,nc)
    dev.off()
    }

ধারণাটি কেবলমাত্র একটি ম্যাট্রিক্সে রেস্টার (ফাইলটি পিএনজিতে থাকতে হবে) হ্রাস করতে হবে যার ঘরের সংখ্যা ১৪০ এর চেয়ে কম, টুইটগুলি তখন দুটি বর্ণের পূর্বে সারিগুলির সংকেত নির্দেশিত একটি বর্ণের (colors৪ টি রঙে) রঙের সেরি এবং রাস্টার এর কলাম।

encoder("Mona_Lisa.png")
[1] ",(XXX000@000000XYi@000000000TXi0000000000TX0000m000h00T0hT@hm000000T000000000000XX00000000000XXi0000000000TXX0000000000"

এখানে চিত্র বর্ণনা লিখুন

encoder("630x418.png") # Not a huge success for this one :)
[1] "(-00000000000000000000EEZZooo00E0ZZooo00Z00Zooo00Zo0oooooEZ0EEZoooooooEZo0oooooo000ooZ0Eo0000oooE0EE00oooEEEE0000000E00000000000"

এখানে চিত্র বর্ণনা লিখুন

encoder("2d shapes.png")
[1] "(,ooooooooooooooooooooo``ooooo0o``oooooooooo33ooooooo33oo0ooooooooooo>>oooo0oooooooo0ooooooooooooolloooo9oolooooooooooo"

এখানে চিত্র বর্ণনা লিখুন

encoder("mountains.png")
[1] "(,_K_K0005:_KKK0005:__OJJ006:_oKKK00O:;;_K[[4OD;;Kooo4_DOKK_o^D_4KKKJ_o5o4KK__oo4_0;K___o5JDo____o5Y0____440444040400D4"

এখানে চিত্র বর্ণনা লিখুন


4

একটি সম্পূর্ণ সমাধান নয়, কেবল পদ্ধতিটি বাইরে রেখে দিন। (মতলব)

আমি একটি 16 টি রঙিন প্যালেট এবং 40 পজিশন একটি ভারিত ভারোনাই চিত্রটি তৈরি করতে ব্যবহার করেছি । চিত্রটি ফিট করার জন্য জেনেটিক অ্যালগরিদম এবং সাধারণ পাহাড়ী-আরোহণের অ্যালগরিদম ব্যবহৃত হয়েছে।

মূল চিত্র সহ অ্যালবাম এবং আমার কাছে 4 টি রঙ এবং স্থির অবস্থানের সাথে একটি 16 বাইট সংস্করণ রয়েছে। :)

এখানে চিত্র বর্ণনা লিখুন

(আমি কি এখানে চিত্রের আকার পরিবর্তন করতে পারি?)


1
আপনি কি অন্যান্য ছবি পোস্ট করতে পারেন? এই সংকোচনের সাথে তারা দেখতে কেমন দেখতে চাই!
jdstankosky

@jdstankosky দুঃখিত, আমি এখন এটি করতে পারি না। সম্ভবত কিছু সময় পরে ...
এলোমেলো

4

সি শার্প

আপডেট - সংস্করণ 2


আমি এটির জন্য আরেকটি চেষ্টা করেছি, এখন জেপিইজি ডেটা এনকোড করতে MagickImage.NET ( https://magick.codeplex.com/ ) ব্যবহার করে, আমি JPEG শিরোনামের ডেটা উন্নত প্রক্রিয়া করার জন্য কিছু বেসিক কোডও লিখেছিলাম (প্রিমো প্রস্তাবিত হিসাবে), আমিও আউটপুটে গাসিয়ানব্লার ব্যবহার করেছেন যা কিছু জেপিইজি সংক্ষেপণকে নরম করতে সহায়তা করে। নতুন সংস্করণটি আরও ভালভাবে উপস্থাপিত হওয়ার সাথে সাথে, আমি আমার পদ্ধতিটি নতুন পদ্ধতির প্রতিবিম্বিত করতে আপডেট করেছি।


পদ্ধতি


বর্ণের গভীরতা, বা প্রান্ত সনাক্তকরণের চেষ্টা না করে বা চিত্রের আকার হ্রাস করার জন্য বিভিন্ন উপায়ে ব্যবহার করার চেষ্টা করার চেয়ে আমি জেপিইজি অ্যালগরিদমকে সর্বাধিক সংক্ষিপ্ত সংস্করণে সর্বাধিক সংকোচনে ব্যবহার করেছি বরং আমি অনন্য কিছু চেষ্টা করেছি (আশা করি) চিত্রগুলি, তারপরে "স্টার্টফ্যানস্ক্যান" ( http://en.wikedia.org/wiki/JPEG# সায়েন্টাক্স_আর_ স্ট্রাকচার ) এবং কয়েকটি মূল শিরোনাম উপাদানগুলি বাদ দিয়ে আমি আকারটি গ্রহণযোগ্য পরিমাণে নামিয়ে আনতে সক্ষম হয়েছি। ফলাফলগুলি 140 টি চরিত্রের জন্য বেশ চিত্তাকর্ষক, আমাকে জেপিইগির জন্য একটি নতুন পাওয়া শ্রদ্ধা দেয়:

হিন্ডেনবার্গ

হিন্ডেনবার্গ মূল

,$`"(b $!   _ &4j6k3Qg2ns2"::4]*;12T|4z*4n*4<T~a4- ZT_%-.13`YZT;??e#=*!Q033*5>z?1Ur;?2i2^j&r4TTuZe2444b*:>z7.:2m-*.z?|*-Pq|*,^Qs<m&?:e-- 

পর্বতমালা

পর্বতমালা মূল

,$  (a`,!  (1 Q$ /P!U%%%,0b*2nr4 %)3t4 +3#UsZf3S2 7-+m1Yqis k2U'm/#"h q2T4#$s.]/)%1T &*,4Ze w$Q2Xqm&: %Q28qiqm Q,48Xq12 _

মোনালিসা

মোনালিসা মূল

23  (a`,!  (1 Q$ /P q1Q2Tc$q0,$9--/!p Ze&:6`#*,Tj6l0qT%(:!m!%(84|TVk0(*2k24P)!e(U,q2x84|Tj*8a1a-%** $r4_--Xr&)12Tj8a2Tj* %r444 %%%% !

আকার

আকার মূল

(ep 1# ,!  (1 Q$ /P"2`#=WTp $X[4 &[Vp p<T +0 cP* 0W=["jY5cZ9(4 (<]t  ]Z %ZT -P!18=V+UZ4" #% i6%r}#"l p QP>*r $!Yq(!]2 jo* zp!0 4 % !0 4 % '!


কোড


সংস্করণ 2 - http://pastebin.com/Tgr8XZUQ

আমি রিশার্পারকে মিস করতে শুরু করছি + আমার কাছে উন্নত করার জন্য প্রচুর জিনিস রয়েছে, এখনও এখানে প্রচুর হার্ড কোডিং বরাদ্দ করা হয়েছে, যদিও মেসেজের সাথে মেসেজ হচ্ছে (মনে রাখবেন ম্যাজিকআইমেজ ডেল এর এটি ভিএসে চালানোর জন্য দরকার)


আসল (অবমূল্যায়িত) - http://pastebin.com/BDPT0BKT

তবুও কিছুটা গণ্ডগোল।


"এটি এখনই সত্যিই জগাখিচুড়ি," আমি এটির সাথে একমত হই - অবশ্যই এই শিরোলেখ উত্পন্ন করার জন্য আরও ভাল উপায় থাকতে হবে? তবে আমি মনে করি ফলাফলগুলি সবচেয়ে গুরুত্বপূর্ণ। +1
প্রিমো

1

পাইথন ঘ

পদ্ধতি

প্রোগ্রামটি প্রথমে যা করে তা হ'ল চিত্রটি কমিয়ে দিচ্ছে, এর আকারটি হ্রাস করছে।

দ্বিতীয়ত, এটি আরজিবি মানগুলিকে বাইনারিতে রূপান্তর করে এবং শেষের কয়েকটি অঙ্ক স্নিপ করে।

তারপরে এটি বেস 2 ডেটা বেস 10 এ রূপান্তর করে, যেখানে এটি ছবির মাত্রা যুক্ত করে।

তারপরে এটি বেস 10 এর ডেটাগুলিকে 95 টি বেসকে রূপান্তর করে, আমি যে সমস্ত এসকিআই খুঁজে পেতে পারি তা ব্যবহার করে। যাইহোক, আমি টেক্সট ফাইলটি লিখে ফাংশনটিকে অস্বীকার করার ক্ষমতার কারণে / x01 এবং এর মতো ব্যবহার করতে পারিনি।

এবং (যুক্ত অস্পষ্টতার জন্য), ডিকোড ফাংশনটি এটি বিপরীতে করে।

compress.py

    from PIL import Image
def FromBase(digits, b): #converts to base 10 from base b
    numerals='''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_-+={[}]|:;"',<.>/?`~\\ '''
    D=[]
    for d in range(0,len(digits)):
        D.append(numerals.index(digits[d]))
    s=0
    D=D[::-1]
    for x in range(0,len(D)):
        s+=D[x]*(b**x)
    return(str(s))
def ToBase(digits,b): #converts from base 10 to base b
    numerals='''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_-+={[}]|:;"',<.>/?`~\\ '''
    d=int(digits)
    D=''
    B=b
    while(B<=d):
        B*=b
    B//=b
    while(B>=1):
        D+=numerals[d//B]
        d-=((d//B)*B)
        B//=b
    return(D)
im=Image.open('1.png')
size=im.size
scale_factor=40
im=im.resize((int(size[0]/scale_factor),int(size[1]/scale_factor)), Image.ANTIALIAS)
a=list(im.getdata())
K=''
for x in a:
    for y in range(0,3):
        Y=bin(x[y])[2:]
        while(len(Y))<9:
            Y='0'+Y
        K+=str(Y)[:-5]
K='1'+K
print(len(K))
K=FromBase(K,2)
K+=str(size[0])
K+=str(size[1])
K=ToBase(K,95)
with open('1.txt', 'w') as outfile:
    outfile.write(K)

decode.py

    from random import randint, uniform
from PIL import Image, ImageFilter
import math
import json
def FromBase(digits, b): #str converts to base 10 from base b
    numerals='''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_-+={[}]|:;"',<.>/?`~\\ \x01\x02\x03\x04\x05\x06\x07'''
    D=[]
    for d in range(0,len(digits)):
        D.append(numerals.index(digits[d]))
    s=0
    D=D[::-1]
    for x in range(0,len(D)):
        s+=D[x]*(b**x)
    return(str(s))
def ToBase(digits,b): #str converts from base 10 to base b
    numerals='''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_-+={[}]|:;"',<.>/?`~\\ \x01\x02\x03\x04\x05\x06\x07'''
    d=int(digits)
    D=''
    B=b
    while(B<=d):
        B*=b
    B//=b
    while(B>=1):
        D+=numerals[d//B]
        d-=((d//B)*B)
        B//=b
    return(D)
scale_factor=40
K=open('1.txt', 'r').read()
K=FromBase(K,95)
size=[int(K[-6:][:-3])//scale_factor,int(K[-6:][-3:])//scale_factor]
K=K[:-6]
K=ToBase(K,2)
K=K[1:]
a=[]
bsize=4
for x in range(0,len(K),bsize*3):
    Y=''
    for y in range(0,bsize*3):
        Y+=K[x+y]
    y=[int(Y[0:bsize]+'0'*(9-bsize)),int(Y[bsize:bsize*2]+'0'*(9-bsize)),int(Y[bsize*2:bsize*3]+'0'*(9-bsize))]
    y[0]=int(FromBase(str(y[0]),2))
    y[1]=int(FromBase(str(y[1]),2))
    y[2]=int(FromBase(str(y[2]),2))
    a.append(tuple(y))
im=Image.new('RGB',size,'black')
im.putdata(a[:size[0]*size[1]])
im=im.resize((int(size[0]*scale_factor),int(size[1]*scale_factor)), Image.ANTIALIAS)
im.save('pic.png')

আর্তনাদ

Scream1 Scream2

hqgyXKInZo9-|A20A*53ljh[WFUYu\;eaf_&Y}V/@10zPkh5]6K!Ur:BDl'T/ZU+`xA4'\}z|8@AY/5<cw /8hQq[dR1S 2B~aC|4Ax"d,nX`!_Yyk8mv6Oo$+k>_L2HNN.#baA

মোনালিসা

মোনা লিসা ঘ মোনা লিসা 2

f4*_!/J7L?,Nd\#q$[f}Z;'NB[vW%H<%#rL_v4l_K_ >gyLMKf; q9]T8r51it$/e~J{ul+9<*nX0!8-eJVB86gh|:4lsCumY4^y,c%e(e3>sv(.y>S8Ve.tu<v}Ww=AOLrWuQ)

গোলকগুলি

গোলক ঘ গোলক 2

})|VF/h2i\(D?Vgl4LF^0+zt$d}<M7E5pTA+=Hr}{VxNs m7Y~\NLc3Q"-<|;sSPyvB[?-B6~/ZHaveyH%|%xGi[Vd*SPJ>9)MKDOsz#zNS4$v?qM'XVe6z\
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.