চিত্রটিতে পিক্সেলগুলি পুনরায় সাজান যাতে এটি সনাক্ত করা যায় না এবং তারপরে এটি ফিরে পান get


86

এমন একটি প্রোগ্রাম তৈরি করুন যা চিত্রটিতে পিক্সেলগুলি পুনরায় সাজিয়ে তুলতে পারে যাতে এটি সনাক্ত করা যায় না। তবে আপনার প্রোগ্রামটিকে এটিকে আবার মূল চিত্রে রূপান্তর করতে সক্ষম করা উচিত।

আপনি দুটি ফাংশন লিখতে পারেন - এনকোডিং এবং ডিকোডিংয়ের জন্য, তবে একটি ফাংশন যা বারবার প্রয়োগ করে তা মূল চিত্র দেয় (গণিতে উদাহরণস্বরূপ f(x) = 1 - x) - এটি একটি বোনাস।

আউটপুট কিছু প্যাটার্ন উত্পাদন খুব বোনাস দেয়।

আপনার ভাষা যদি সমর্থন করে তবে চিত্রটি 1D / 2D অ্যারে বা চিত্র অবজেক্ট হিসাবে উপস্থাপিত হতে পারে। নোট করুন যে আপনি কেবল পিক্সেলের ক্রম পরিবর্তন করতে পারেন!

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

পরীক্ষার চিত্র 1 (800 x 422 পিক্স): পরীক্ষার চিত্র 2 (800 x 480 px): দয়া করে কোড আউটপুট চিত্র সরবরাহ করুন।


প্রশ্নটি "চিত্রগুলির জন্য একটি এনক্রিপশন অ্যালগরিদম লিখুন, যার আউটপুট একটি চিত্র" saying
ডেভিড রিচার্বি

3
@ ডেভিডরিচার্বি… এটি একই পিক্সেল / রঙ ব্যবহার করে। "প্লেইন ইমেজ" এ পাঁচটি কালো পিক্সেল -> "সাইফার ইমেজ" এ পাঁচটি কালো পিক্সেল।
ড্যানিয়েল বেক

2
@ user2992539 ঠিক আছে, সেক্ষেত্রে আপনি স্পষ্টভাবে বলতে চাইবেন যে এটি টাই ব্রেকার হিসাবে ব্যবহৃত হয়। অন্যথায়, এটি কেবল বোনাস বলা খুব অর্থবহ নয়।
মার্টিন ইন্ডার

3
এই প্রশ্নটি আমাকে আর্নল্ডের বিড়ালের মানচিত্র সম্পর্কে ভাবতে বাধ্য করেছিল । আমি মনে করি না যে এটি এই উদ্দেশ্যে যথেষ্ট উপযুক্ত তবে এটি একইভাবে আকর্ষণীয় - মানচিত্রে যথেষ্ট সময় পুনরাবৃত্তি করা আপনাকে আসল চিত্রটিতে ফিরে আসে।
ট্রাইকোপলাক্স

4
এখন অন্যত্র স্ট্যাক এক্সচেঞ্জ নেটওয়ার্কে: Security.SE সব জায়গায়
Doorknob

উত্তর:


58

পাইথন ২.7 (পিআইএল সহ) - সিউডোর্যান্ডমনেস নেই

আমি ছবিটি 2 বাই 2 ব্লকে বিভক্ত করে রেখেছি (বাকী অংশগুলি উপেক্ষা করে) এবং প্রতিটি ব্লককে 180 ডিগ্রি দ্বারা ঘোরান, তারপরে আমি কিছু পরামিতি বিএলকেএসজেড পর্যন্ত 3 বাই 3 ব্লক, তারপর 4 ইত্যাদি দিয়ে একই কাজ করি। তারপরে আমি বিএলকেএসজেড -১, তারপরে বিএলকেএসজেড -২ এর জন্য একই পদ্ধতিটি 3 এর নিচে ফিরে যাই, তারপর ২. এই পদ্ধতিটি নিজেকে ঠিক বিপরীত করে; আনস্র্যাম্বল ফাংশন হ'ল স্ক্র্যাম্বেল ফাংশন।

কোড :

from PIL import Image
import math

im = Image.open("ST1.png", "r")
arr = im.load() #pixel data stored in this 2D array

def rot(A, n, x1, y1): #this is the function which rotates a given block
    temple = []
    for i in range(n):
        temple.append([])
        for j in range(n):
            temple[i].append(arr[x1+i, y1+j])
    for i in range(n):
        for j in range(n):
            arr[x1+i,y1+j] = temple[n-1-i][n-1-j]


xres = 800
yres = 480
BLKSZ = 50 #blocksize
for i in range(2, BLKSZ+1):
    for j in range(int(math.floor(float(xres)/float(i)))):
        for k in range(int(math.floor(float(yres)/float(i)))):
            rot(arr, i, j*i, k*i)
for i in range(3, BLKSZ+1):
    for j in range(int(math.floor(float(xres)/float(BLKSZ+2-i)))):
        for k in range(int(math.floor(float(yres)/float(BLKSZ+2-i)))):
            rot(arr, BLKSZ+2-i, j*(BLKSZ+2-i), k*(BLKSZ+2-i))

im.save("ST1OUT "+str(BLKSZ)+".png")

print("Done!")

ব্লকসাইজের উপর নির্ভর করে, আপনি গণনাটি মূল চিত্রের সাথে সমস্ত সাদৃশ্যটি নির্মূল করতে পারেন: (বিএলকেএসজেড = 50) এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

বা গণনাকে দক্ষ করে তোলা: (BLKSZ = 10) এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন


6
সেরা ফলাফলের মতো শব্দটি যদি BLKSZ চিত্রের আকারের প্রায় অর্ধেক হয়। যাইহোক, আমি অ্যালগরিদম পছন্দ করি এবং ছোট বিএলকেএসজেডের কাছে এটি একটি আধুনিক শিল্পের মতো লাগে! কুল!
সোমনিয়াম

11
আমি সর্বদা অজগরকে উপড়ে ফেলেছি।
qwr

2 থেকে 50 পর্যন্ত সমস্ত মানের জন্য ঝাঁকুনির পরিবর্তে, সম্ভবত আপনার কেবল প্রাথমিক সংখ্যা ব্যবহার করা উচিত?
নীল

@ নিল সম্ভবত এটি আরও এলোমেলো এবং কম শৈল্পিক দেখায়।
সোমনিয়াম

BLKSZ = 10ভূদৃশ্য সত্যিই শীতল হয়!
wchargin

52

সি #, উইনফর্ম

সম্পাদনা করুন আপনি স্থানাঙ্ক অ্যারের ভরাট আপনি বিভিন্ন নিদর্শন থাকতে পারে পরিবর্তন - নিচে দেখুন

আপনি কি এই ধরণের প্যাটার্ন পছন্দ করেন?

ভূদৃশ্য

বিমূর্ত

বোনাস:

চিত্কার চিৎকার স্ক্যাম্বলড

নিম্নার্ধে সমস্ত পিক্সেল সহ উপরের অর্ধেকের সমস্ত পিক্সেল ঠিক একসময় এলোমেলো। আনস্ক্র্যাম্বলিংয়ের জন্য একই পদ্ধতিটি পুনরাবৃত্তি করুন (বোনাস)।

কোড

Scramble.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.IO;

namespace Palette
{
    public partial class Scramble : Form
    {
        public Scramble()
        {
            InitializeComponent();
        }

        public struct Coord
        {
            public int x, y;
        }

        private void Work(Bitmap srcb, Bitmap outb)
        {
            int w = srcb.Width, h = srcb.Height;
            Coord[] coord = new Coord[w * h];

            FastBitmap fsb = new FastBitmap(srcb);
            FastBitmap fob = new FastBitmap(outb);
            fsb.LockImage();
            fob.LockImage();
            ulong seed = 0;
            int numpix = 0;
            for (int y = 0; y < h; y++)
                for (int x = 0; x < w; numpix++, x++)
                {
                    coord[numpix].x = x;
                    coord[numpix].y = y;
                    uint color = fsb.GetPixel(x, y);
                    seed += color;
                    fob.SetPixel(x, y, color);
                }
            fsb.UnlockImage();
            fob.UnlockImage();
            pbOutput.Refresh();
            Application.DoEvents();

            int half = numpix / 2;
            int limit = half;
            XorShift rng = new XorShift(seed);
            progressBar.Visible = true;
            progressBar.Maximum = limit;

            fob.LockImage();
            while (limit > 0)
            {
                int p = (int)(rng.next() % (uint)limit);
                int q = (int)(rng.next() % (uint)limit);
                uint color = fob.GetPixel(coord[p].x, coord[p].y); 
                fob.SetPixel(coord[p].x, coord[p].y, fob.GetPixel(coord[half+q].x, coord[half+q].y)); 
                fob.SetPixel(coord[half+q].x, coord[half+q].y, color); 
                limit--;
                if (p < limit)
                {
                    coord[p]=coord[limit];
                }
                if (q < limit)
                {
                    coord[half+q]=coord[half+limit];
                }
                if ((limit & 0xfff) == 0)
                {
                    progressBar.Value = limit;
                    fob.UnlockImage();
                    pbOutput.Refresh();
                    fob.LockImage();
                }
            }
            fob.UnlockImage();
            pbOutput.Refresh();
            progressBar.Visible = false; 
        }

        void DupImage(PictureBox s, PictureBox d)
        {
            if (d.Image != null)
                d.Image.Dispose();
            d.Image = new Bitmap(s.Image.Width, s.Image.Height);  
        }

        void GetImagePB(PictureBox pb, string file)
        {
            Bitmap bms = new Bitmap(file, false);
            Bitmap bmp = bms.Clone(new Rectangle(0, 0, bms.Width, bms.Height), PixelFormat.Format32bppArgb);
            bms.Dispose(); 
            if (pb.Image != null)
                pb.Image.Dispose();
            pb.Image = bmp;
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.InitialDirectory = "c:\\temp\\";
            openFileDialog.Filter = "Image Files(*.BMP;*.JPG;*.PNG)|*.BMP;*.JPG;*.PNG|All files (*.*)|*.*";
            openFileDialog.FilterIndex = 1;
            openFileDialog.RestoreDirectory = true;

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    string file = openFileDialog.FileName;
                    GetImagePB(pbInput, file);
                    pbInput.Tag = file;
                    DupImage(pbInput, pbOutput);
                    Work(pbInput.Image as Bitmap, pbOutput.Image as Bitmap);
                    file = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(file) + ".scr.png";
                    pbOutput.Image.Save(file);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
                }

            }
        }
    }

    //Adapted from Visual C# Kicks - http://www.vcskicks.com/
    unsafe public class FastBitmap
    {
        private Bitmap workingBitmap = null;
        private int width = 0;
        private BitmapData bitmapData = null;
        private Byte* pBase = null;

        public FastBitmap(Bitmap inputBitmap)
        {
            workingBitmap = inputBitmap;
        }

        public BitmapData LockImage()
        {
            Rectangle bounds = new Rectangle(Point.Empty, workingBitmap.Size);

            width = (int)(bounds.Width * 4 + 3) & ~3;

            //Lock Image
            bitmapData = workingBitmap.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            pBase = (Byte*)bitmapData.Scan0.ToPointer();
            return bitmapData;
        }

        private uint* pixelData = null;

        public uint GetPixel(int x, int y)
        {
            pixelData = (uint*)(pBase + y * width + x * 4);
            return *pixelData;
        }

        public uint GetNextPixel()
        {
            return *++pixelData;
        }

        public void GetPixelArray(int x, int y, uint[] Values, int offset, int count)
        {
            pixelData = (uint*)(pBase + y * width + x * 4);
            while (count-- > 0)
            {
                Values[offset++] = *pixelData++;
            }
        }

        public void SetPixel(int x, int y, uint color)
        {
            pixelData = (uint*)(pBase + y * width + x * 4);
            *pixelData = color;
        }

        public void SetNextPixel(uint color)
        {
            *++pixelData = color;
        }

        public void UnlockImage()
        {
            workingBitmap.UnlockBits(bitmapData);
            bitmapData = null;
            pBase = null;
        }
    }

    public class XorShift
    {
        private ulong x; /* The state must be seeded with a nonzero value. */

        public XorShift(ulong seed)
        {
            x = seed;
        }

        public ulong next()
        {
            x ^= x >> 12; // a
            x ^= x << 25; // b
            x ^= x >> 27; // c
            return x * 2685821657736338717L;
        }
    }
} 

Scramble.designer.cs

namespace Palette
{
    partial class Scramble
    {
        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.panel = new System.Windows.Forms.FlowLayoutPanel();
            this.pbInput = new System.Windows.Forms.PictureBox();
            this.pbOutput = new System.Windows.Forms.PictureBox();
            this.progressBar = new System.Windows.Forms.ProgressBar();
            this.btnOpen = new System.Windows.Forms.Button();
            this.panel.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.pbInput)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pbOutput)).BeginInit();
            this.SuspendLayout();
            // 
            // panel
            // 
            this.panel.AutoScroll = true;
            this.panel.AutoSize = true;
            this.panel.Controls.Add(this.pbInput);
            this.panel.Controls.Add(this.pbOutput);
            this.panel.Dock = System.Windows.Forms.DockStyle.Top;
            this.panel.Location = new System.Drawing.Point(0, 0);
            this.panel.Name = "panel";
            this.panel.Size = new System.Drawing.Size(748, 306);
            this.panel.TabIndex = 3;
            // 
            // pbInput
            // 
            this.pbInput.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pbInput.Location = new System.Drawing.Point(3, 3);
            this.pbInput.MinimumSize = new System.Drawing.Size(100, 100);
            this.pbInput.Name = "pbInput";
            this.pbInput.Size = new System.Drawing.Size(100, 300);
            this.pbInput.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.pbInput.TabIndex = 3;
            this.pbInput.TabStop = false;
            // 
            // pbOutput
            // 
            this.pbOutput.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pbOutput.Location = new System.Drawing.Point(109, 3);
            this.pbOutput.MinimumSize = new System.Drawing.Size(100, 100);
            this.pbOutput.Name = "pbOutput";
            this.pbOutput.Size = new System.Drawing.Size(100, 300);
            this.pbOutput.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.pbOutput.TabIndex = 4;
            this.pbOutput.TabStop = false;
            // 
            // progressBar
            // 
            this.progressBar.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.progressBar.Location = new System.Drawing.Point(0, 465);
            this.progressBar.Name = "progressBar";
            this.progressBar.Size = new System.Drawing.Size(748, 16);
            this.progressBar.TabIndex = 5;
            // 
            // btnOpen
            // 
            this.btnOpen.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.btnOpen.Location = new System.Drawing.Point(12, 429);
            this.btnOpen.Name = "btnOpen";
            this.btnOpen.Size = new System.Drawing.Size(53, 30);
            this.btnOpen.TabIndex = 6;
            this.btnOpen.Text = "Start";
            this.btnOpen.UseVisualStyleBackColor = true;
            this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click);
            // 
            // Scramble
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.BackColor = System.Drawing.SystemColors.ControlDark;
            this.ClientSize = new System.Drawing.Size(748, 481);
            this.Controls.Add(this.btnOpen);
            this.Controls.Add(this.progressBar);
            this.Controls.Add(this.panel);
            this.Name = "Scramble";
            this.Text = "Form1";
            this.panel.ResumeLayout(false);
            this.panel.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.pbInput)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pbOutput)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }


        private System.Windows.Forms.FlowLayoutPanel panel;
        private System.Windows.Forms.PictureBox pbOutput;
        private System.Windows.Forms.ProgressBar progressBar;
        private System.Windows.Forms.PictureBox pbInput;
        private System.Windows.Forms.Button btnOpen;
    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Palette
{
  static class Program
  {
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Scramble());
    }
  }
}

সংকলনের জন্য প্রকল্পের সম্পত্তিটিতে 'অনিরাপদ কোড' পরীক্ষা করুন।

জটিল প্যাটার্ন

হামাগুড়ি দিয়া আরোহণ

অ্যাপ্লিকেশন অবধি কাজের ফাংশনের প্রথম অংশটি পরিবর্তন করুন o

        int w = srcb.Width, h = srcb.Height;
        string Msg = "Scramble";

        Graphics gr = Graphics.FromImage(outb);

        Font f = new Font("Arial", 100, FontStyle.Bold);
        var size = gr.MeasureString(Msg, f);
        f = new Font("Arial", w / size.Width * 110, FontStyle.Bold);
        size = gr.MeasureString(Msg, f);
        gr.DrawString(Msg, f, new SolidBrush(Color.White), (w - size.Width) / 2, (h - size.Height) / 2);

        gr.Dispose();

        Coord[] coord = new Coord[w * h];
        FastBitmap fsb = new FastBitmap(srcb);
        FastBitmap fob = new FastBitmap(outb);
        fsb.LockImage();
        fob.LockImage();
        ulong seed = 1;
        int numpix = h * w;
        int c1 = 0, c2 = numpix;
        int y2 = h / 2;

        int p2 = numpix/2;

        for (int p = 0; p < p2; p++)
        {
            for (int s = 1; s > -2; s -= 2)
            {
                int y = (p2+s*p) / w;
                int x = (p2+s*p) % w;

                uint d = fob.GetPixel(x, y);
                if (d != 0)
                {
                    c2--;
                    coord[c2].x = x;
                    coord[c2].y = y;
                }
                else
                {
                    coord[c1].x = x;
                    coord[c1].y = y;
                    c1++;
                }
                fob.SetPixel(x, y, fsb.GetPixel(x, y));
            }
        }
        fsb.UnlockImage();
        fob.UnlockImage();
        pbOutput.Refresh();
        Application.DoEvents();

1
আকর্ষণীয়) আমি ভাবছি যে একই ধরণের পদ্ধতির সাথে আউটপুটটিতে আরও জটিল নিদর্শন তৈরি করা সম্ভব কিনা।
সোমনিয়াম

1
সুন্দর ধারণা - যখন বিজোড় সংখ্যক লাইনের মধ্যবর্তী লাইনের সাথে কী ঘটে?
flawr

1
@ ফ্লোয়ার স্প্লিট প্রতি পিক্সেল হয়। যদি পিক্সেলের একটি বিজোড় সংখ্যা থাকে তবে শেষটি কোনওটি অচিহ্নত থাকে। যদি সারিগুলির একটি বিজোড় সংখ্যা হয় তবে মাঝারি সারির বাম অর্ধেকটি 'উপরের দিক' এবং ডান অর্ধেকটি 'নিম্ন পাশ'।
edc65 21

1
@ ব্যবহারকারী 2992539 আমি মনে করি আপনি আরও - এমনকি চেকবোর্ডকে আরও বিয়োগ করতে পারেন can আরও মহকুমা সহ, চিত্রটি আরও বেশি স্বীকৃত।
edc65

7
আপনার "স্ক্র্যাম্বেল" সংস্করণটি পছন্দ করুন!)
সোমনিয়াম

43

সি, নির্বিচারে অস্পষ্টতা, সহজেই বিপরীতমুখী

পার্টিতে লে। এখানে আমার প্রবেশ!

এই পদ্ধতিটি একটি ঝাপসা ঝাপসা করে। আমি একে স্ক্র্যাম্বলুর বলি । এটি অত্যন্ত সহজ। একটি লুপে, এটি একটি এলোমেলো পিক্সেল চয়ন করে এবং তারপরে এলোমেলোভাবে বেছে নেওয়া নিকটবর্তী পিক্সেলটি টেরয়েডাল ক্যানভাস মডেলের সাথে সরিয়ে দেয়। আপনি "নিকটবর্তী পিক্সেল" এর অর্থ (1 অর্থ সর্বদা একটি সংলগ্ন পিক্সেল চয়ন করুন), পুনরাবৃত্তির সংখ্যা এবং বৈকল্পিকভাবে একটি এলোমেলো সংখ্যা বীজ নির্ধারণ করে সর্বাধিক দূরত্ব নির্দিষ্ট করেন specify সর্বাধিক দূরত্বের বৃহত্তর এবং পুনরাবৃত্তির সংখ্যা বৃহত্তর, ফলকে ঝাপসা করে।

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

ডেমো

প্রথম দুটি চিত্রের জন্য, আপনি নীচে স্ক্রোল করার সাথে সাথে প্রতিটি চিত্র উচ্চতর সর্বাধিক অফসেট ব্যবহার করে ঝাপসা হয়ে গেছে: শীর্ষস্থানীয় মূল চিত্রটি (উদাহরণস্বরূপ, 0-পিক্সেল অফসেট), তারপরে 1, 2, 4, 8, 16, 32, 64 , 128 এবং অবশেষে 256. নীচের সমস্ত চিত্রের জন্য পুনরাবৃত্তির গণনা 10⁶ = 1,000,000।

দ্বিতীয় দুটি চিত্রের জন্য, প্রতিটি চিত্র একটি ধীরে ধীরে কম অফসেট - উদাহরণস্বরূপ, সবচেয়ে ঝাপসা থেকে কমপক্ষে অস্পষ্ট - সর্বাধিক 256 এর অফসেট থেকে নীচে 0 টি ব্যবহার করে ঝাপসা হয়ে গেছে! উপভোগ করুন!

ভূদৃশ্য বিমূর্ত

এবং এই পরবর্তী দুটি চিত্রের জন্য, আপনি এখানে এবং এখানে পূর্ণ-আকারের অগ্রগতি দেখতে পাবেন :

খারাপ ব্রেকিং সিম্পসনস

কোড

আজ সকালে ঘুম থেকে ওঠার সময় আমি প্রায় এক ঘন্টার মধ্যে এটি একত্রে হ্যাক করেছি এবং এতে প্রায় কোনও ডকুমেন্টেশন নেই। আমি কয়েক দিনের মধ্যে ফিরে আসতে পারি এবং লোকেরা এটির জন্য অনুরোধ করলে পরে আরও ডকুমেন্টেশন যুক্ত করতে পারে।

//=============================================================================
// SCRAMBLUR
//
// This program is a image-processing competition entry which scrambles or
// descrambles an image based on a pseudorandom process.  For more details,
// information, see:
//
//    http://codegolf.stackexchange.com/questions/35005
//
// It is assumed that you have the NETPBM package of image-processing tools
// installed on your system.  This can be obtained from:
//
//    http://netpbm.sourceforge.net/
//
// or by using your system's package manager, e.g., yum, apt-get, port, etc.
//
// Input to the program is a 24-bit PNM image (type "P6").  Output is same.
// Example command-line invocation:
//
// pngtopnm original.png  | scramblur 100  1000000 | pnmtopng >scrambled.png
// pngtopnm scrambled.png | scramblur 100 -1000000 | pnmtopng >recovered.png
//
//
// Todd S. Lehman, July 2014

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

typedef uint8_t uint8;
typedef uint64_t uint64;

//-----------------------------------------------------------------------------
// PIXEL STRUCTURE

#pragma pack(push, 1)
typedef struct
{
  uint8 r, g, b;     // Red, green, and blue color components
}
Pixel;
#pragma pack(pop)

//-----------------------------------------------------------------------------
// IMAGE STRUCTURE

typedef struct
{
  int width;          // Width of image in pixels
  int height;         // Height of image in pixels
  int pixel_count;    // Total number of pixels in image (e.g., width * height)
  int maxval;         // Maximum pixel component value (e.g., 255)
  Pixel *data;        // One-dimensional array of pixels
}
Image;

//-----------------------------------------------------------------------------
// 64-BIT LCG TABLE

static const long lcg64_table_length = 1000000;  // 10⁶ entries => 8 Megabytes

static uint64 lcg64_table[lcg64_table_length];

//-----------------------------------------------------------------------------
// GET 64-BIT LCG VALUE FROM TABLE

uint64 lcg64_get(long const iteration)
{
  return lcg64_table[iteration % lcg64_table_length];
}

//-----------------------------------------------------------------------------
// INITIALIZE 64-BIT LCG TABLE

void lcg64_init(uint64 const seed)
{
  uint64 x = seed;
  for (long iteration = 0; iteration < lcg64_table_length; iteration++)
  {
    uint64 const a = UINT64_C(6364136223846793005);
    uint64 const c = UINT64_C(1442695040888963407);
    x = (x * a) + c;
    lcg64_table[iteration] = x;
  }
}

//-----------------------------------------------------------------------------
// READ BINARY PNM IMAGE

Image image_read(FILE *const file)
{
  Image image = { .data = NULL };

  char *line = NULL;
  size_t linecap = 0;

  // Read image type.  (Currently only P6 is supported here.)
  if (getline(&line, &linecap, file) < 0) goto failure;
  if (strcmp(line, "P6\n") != 0) goto failure;

  // Read width and height of image in pixels.
  {
    if (getline(&line, &linecap, file) < 0) goto failure;
    char *pwidth = &line[0];
    char *pheight = strchr(line, ' ');
    if (pheight != NULL) pheight++; else goto failure;
    image.width = atoi(pwidth);
    image.height = atoi(pheight);
    image.pixel_count = image.width * image.height;
  }

  // Read maximum color value.  (Currently only 255 is supported here.)
  {
    if (getline(&line, &linecap, file) < 0) goto failure;
    image.maxval = atoi(line);
    if (image.maxval != 255)
      goto failure;
  }

  // Allocate image buffer and read image data.
  if (!(image.data = calloc(image.pixel_count, sizeof(Pixel))))
    goto failure;

  if (fread(image.data, sizeof(Pixel), image.pixel_count, file) !=
      image.pixel_count)
    goto failure;

success:
  free(line);
  return image;

failure:
  free(line);
  free(image.data); image.data = NULL;
  return image;
}

//-----------------------------------------------------------------------------
// WRITE BINARY PNM IMAGE

void image_write(const Image image, FILE *const file)
{
  printf("P6\n");
  printf("%d %d\n", image.width, image.height);
  printf("%d\n", image.maxval);
  (void)fwrite(image.data, sizeof(Pixel), image.pixel_count, file);
}

//-----------------------------------------------------------------------------
// DISCARD IMAGE

void image_discard(Image image)
{
  free(image.data);
}

//-----------------------------------------------------------------------------
// SCRAMBLE OR UNSCRAMBLE IMAGE

void image_scramble(Image image,
                    int const max_delta,
                    long const iterations,
                    uint64 const lcg64_seed)
{
  if (max_delta == 0) return;

  int neighborhood1 = (2 * max_delta) + 1;
  int neighborhood2 = neighborhood1 * neighborhood1;

  lcg64_init(lcg64_seed);

  long iteration_start = (iterations >= 0)? 0 : -iterations;
  long iteration_end   = (iterations >= 0)? iterations : 0;
  long iteration_inc   = (iterations >= 0)? 1 : -1;

  for (long iteration = iteration_start;
       iteration != iteration_end;
       iteration += iteration_inc)
  {
    uint64 lcg64 = lcg64_get(iteration);

    // Choose random pixel.
    int pixel_index = (int)((lcg64 >> 0) % image.pixel_count);

    // Choose random pixel in the neighborhood.
    int d2 = (int)((lcg64 >> 8) % neighborhood2);
    int dx = (d2 % neighborhood1) - (neighborhood1 / 2);
    int dy = (d2 / neighborhood1) - (neighborhood1 / 2);
    int other_pixel_index = pixel_index + dx + (dy * image.width);
    while (other_pixel_index < 0)
      other_pixel_index += image.pixel_count;
    other_pixel_index %= image.pixel_count;

    // Swap pixels.
    Pixel t = image.data[pixel_index];
    image.data[pixel_index] = image.data[other_pixel_index];
    image.data[other_pixel_index] = t;
  }
}

//-----------------------------------------------------------------------------
int main(const int argc, char const *const argv[])
{
  int max_delta     = (argc > 1)? atoi(argv[1]) : 1;
  long iterations   = (argc > 2)? atol(argv[2]) : 1000000;
  uint64 lcg64_seed = (argc > 3)? (uint64)strtoull(argv[3], NULL, 10) : 0;

  Image image = image_read(stdin);
  if (!image.data) { fprintf(stderr, "Invalid input\n"), exit(1); }

  image_scramble(image, max_delta, iterations, lcg64_seed);

  image_write(image, stdout);

  image_discard(image);

  return 0;
}

4
এই উত্তরের সবেমাত্র স্ক্রোল করা, দুর্দান্ত দেখায়
টমাস

1
এই উত্তরটি আসলেই লম্বা। আপনি কি মনে করেন যে আপনি অতিরিক্ত চিত্রগুলি (যেমন দুটি পরীক্ষার চিত্র বাদে সব কিছু পুরোপুরি অস্পষ্ট) অফ-সাইট গ্যালারীটিতে স্থানান্তর করতে পারেন?
টিম এস

@TimS। - সম্পন্ন! ছোট ছোট থাম্বনেইলে তাদের সঙ্কুচিত করুন।
টড লেহম্যান

42

পাইথন ৩.৪

  • বোনাস 1: স্ব বিপরীত: পুনরাবৃত্তি আসল চিত্রটি পুনরুদ্ধার করে।
  • Keyচ্ছিক কী চিত্র: মূল চিত্রটি আবার একই কী চিত্র ব্যবহার করে পুনরুদ্ধার করা যেতে পারে।
  • বোনাস 2: আউটপুটে উত্পাদনের প্যাটার্ন: কী চিত্রটি স্ক্র্যাম্বলড পিক্সেলগুলিতে প্রায় অনুমান হয়।

বোনাস 2 অর্জন করা হলে, অতিরিক্ত কী চিত্র ব্যবহার করে, বোনাস 1 হারাবে না। প্রোগ্রামটি আবার স্ব-বিপরীত, শর্ত থাকে যে এটি আবার একই কী চিত্র সহ পরিচালিত হয়।

স্ট্যান্ডার্ড ব্যবহার

পরীক্ষার চিত্র 1:

স্ক্যাম্বলড টেস্ট ইমেজ 1

পরীক্ষার চিত্র 2:

স্ক্যাম্বলড টেস্ট ইমেজ 2

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

স্ক্র্যাম্বলিং প্রক্রিয়াটি স্ব-বিপরীত কারণ সমস্ত পিক্সেলের তালিকা 2-চক্রের মধ্যে বিভক্ত হয়, যাতে প্রতিটি পিক্সেল এক এবং অন্য একটি পিক্সেলের সাথে অদলবদল হয়। এটি দ্বিতীয়বার চালানো পিক্সেলটির সাথে প্রতিটি পিক্সেলকে অদলবদল করে এটি প্রথমে অদলবদল করে, কীভাবে এটি শুরু হয়েছিল তার সবকিছু ফিরিয়ে দেয়। যদি পিক্সেলের একটি বিজোড় সংখ্যা থাকে তবে এমন একটি থাকবে যা সরবে না।

প্রথমত দ্বি -চক্রের পরামর্শ হিসাবে এমএফভিওনের উত্তরের জন্য ধন্যবাদ ।

একটি মূল চিত্র সহ ব্যবহার

মূল চিত্র হিসাবে টেস্ট চিত্র 2 সহ স্ক্র্যাম্বলিং টেস্ট চিত্র 1

পরীক্ষা 2 সহ স্ক্যামبل পরীক্ষা 1 1

মূল চিত্র হিসাবে টেস্ট চিত্র 1 সহ স্ক্র্যাম্বলিং টেস্ট চিত্র 2

পরীক্ষার সাথে স্ক্যাম্বল পরীক্ষা 2

দ্বিতীয় চিত্রের ফাইল আর্গুমেন্ট (মূল চিত্র) দিয়ে প্রোগ্রামটি চালানো মূল চিত্রটিকে মূল চিত্রের ভিত্তিতে অঞ্চলগুলিতে বিভক্ত করে। এই অঞ্চলগুলির প্রতিটি পৃথকভাবে 2-চক্রে বিভক্ত, যাতে সমস্ত স্ক্র্যাম্বলিং অঞ্চলগুলির মধ্যে ঘটে এবং পিক্সেলগুলি এক অঞ্চল থেকে অন্য অঞ্চলে সরানো হয় না। এটি প্রতিটি অঞ্চলে পিক্সেলগুলি ছড়িয়ে দেয় এবং তাই অঞ্চলগুলি অভিন্ন দাগযুক্ত রঙে পরিণত হয় তবে প্রতিটি অঞ্চলের জন্য কিছুটা আলাদা গড় রঙ থাকে। এটি ভুল রঙগুলিতে মূল চিত্রটির একটি খুব মোটামুটি পরিমাণ দেয়।

আবার দৌড়ানো প্রতিটি অঞ্চলে একই জোড়া পিক্সেল অদলবদল করে, তাই প্রতিটি অঞ্চল তার মূল অবস্থায় ফিরে আসে এবং পুরো চিত্রটি আবার প্রদর্শিত হয়।

অঞ্চলগুলিতে চিত্রটি বিভক্ত করার পরামর্শ হিসাবে প্রথম হিসাবে edc65 এর উত্তরের জন্য ধন্যবাদ । আমি এটিকে স্বেচ্ছাসেবী অঞ্চলগুলি ব্যবহার করার জন্য প্রসারিত করতে চেয়েছিলাম, তবে অঞ্চল 2 এর সমস্ত কিছু দিয়ে অঞ্চল 1 এর সমস্ত কিছু অদলবদলের পদ্ধতির অর্থ এই অঞ্চলগুলি অভিন্ন আকারের হতে হবে। আমার সমাধান হ'ল অঞ্চলগুলি একে অপর থেকে অন্তরক রাখা এবং কেবল প্রতিটি অঞ্চলকে নিজের মধ্যে পরিবর্তন করা। যেহেতু অঞ্চলগুলি আর আকারের হওয়ার দরকার নেই তাই নির্বিচারে আকারের অঞ্চলগুলি প্রয়োগ করা সহজ হয়ে যায়।

কোড

import os.path
from PIL import Image   # Uses Pillow, a fork of PIL for Python 3
from random import randrange, seed


def scramble(input_image_filename, key_image_filename=None,
             number_of_regions=16777216):
    input_image_path = os.path.abspath(input_image_filename)
    input_image = Image.open(input_image_path)
    if input_image.size == (1, 1):
        raise ValueError("input image must contain more than 1 pixel")
    number_of_regions = min(int(number_of_regions),
                            number_of_colours(input_image))
    if key_image_filename:
        key_image_path = os.path.abspath(key_image_filename)
        key_image = Image.open(key_image_path)
    else:
        key_image = None
        number_of_regions = 1
    region_lists = create_region_lists(input_image, key_image,
                                       number_of_regions)
    seed(0)
    shuffle(region_lists)
    output_image = swap_pixels(input_image, region_lists)
    save_output_image(output_image, input_image_path)


def number_of_colours(image):
    return len(set(list(image.getdata())))


def create_region_lists(input_image, key_image, number_of_regions):
    template = create_template(input_image, key_image, number_of_regions)
    number_of_regions_created = len(set(template))
    region_lists = [[] for i in range(number_of_regions_created)]
    for i in range(len(template)):
        region = template[i]
        region_lists[region].append(i)
    odd_region_lists = [region_list for region_list in region_lists
                        if len(region_list) % 2]
    for i in range(len(odd_region_lists) - 1):
        odd_region_lists[i].append(odd_region_lists[i + 1].pop())
    return region_lists


def create_template(input_image, key_image, number_of_regions):
    if number_of_regions == 1:
        width, height = input_image.size
        return [0] * (width * height)
    else:
        resized_key_image = key_image.resize(input_image.size, Image.NEAREST)
        pixels = list(resized_key_image.getdata())
        pixel_measures = [measure(pixel) for pixel in pixels]
        distinct_values = list(set(pixel_measures))
        number_of_distinct_values = len(distinct_values)
        number_of_regions_created = min(number_of_regions,
                                        number_of_distinct_values)
        sorted_distinct_values = sorted(distinct_values)
        while True:
            values_per_region = (number_of_distinct_values /
                                 number_of_regions_created)
            value_to_region = {sorted_distinct_values[i]:
                               int(i // values_per_region)
                               for i in range(len(sorted_distinct_values))}
            pixel_regions = [value_to_region[pixel_measure]
                             for pixel_measure in pixel_measures]
            if no_small_pixel_regions(pixel_regions,
                                      number_of_regions_created):
                break
            else:
                number_of_regions_created //= 2
        return pixel_regions


def no_small_pixel_regions(pixel_regions, number_of_regions_created):
    counts = [0 for i in range(number_of_regions_created)]
    for value in pixel_regions:
        counts[value] += 1
    if all(counts[i] >= 256 for i in range(number_of_regions_created)):
        return True


def shuffle(region_lists):
    for region_list in region_lists:
        length = len(region_list)
        for i in range(length):
            j = randrange(length)
            region_list[i], region_list[j] = region_list[j], region_list[i]


def measure(pixel):
    '''Return a single value roughly measuring the brightness.

    Not intended as an accurate measure, simply uses primes to prevent two
    different colours from having the same measure, so that an image with
    different colours of similar brightness will still be divided into
    regions.
    '''
    if type(pixel) is int:
        return pixel
    else:
        r, g, b = pixel[:3]
        return r * 2999 + g * 5869 + b * 1151


def swap_pixels(input_image, region_lists):
    pixels = list(input_image.getdata())
    for region in region_lists:
        for i in range(0, len(region) - 1, 2):
            pixels[region[i]], pixels[region[i+1]] = (pixels[region[i+1]],
                                                      pixels[region[i]])
    scrambled_image = Image.new(input_image.mode, input_image.size)
    scrambled_image.putdata(pixels)
    return scrambled_image


def save_output_image(output_image, full_path):
    head, tail = os.path.split(full_path)
    if tail[:10] == 'scrambled_':
        augmented_tail = 'rescued_' + tail[10:]
    else:
        augmented_tail = 'scrambled_' + tail
    save_filename = os.path.join(head, augmented_tail)
    output_image.save(save_filename)


if __name__ == '__main__':
    import sys
    arguments = sys.argv[1:]
    if arguments:
        scramble(*arguments[:3])
    else:
        print('\n'
              'Arguments:\n'
              '    input image          (required)\n'
              '    key image            (optional, default None)\n'
              '    number of regions    '
              '(optional maximum - will be as high as practical otherwise)\n')

জেপিইজি চিত্র বার্ন

.jpg ফাইলগুলি খুব দ্রুত প্রক্রিয়াজাত করা হয়, তবে খুব গরম চালানোর জন্য ব্যয় হয়। আসলটি পুনরুদ্ধার করার পরে এটি চিত্রের পরে জ্বলন্ত স্থান ছেড়ে দেয়:

jpg বার্ন

তবে গুরুতরভাবে, একটি ক্ষতির বিন্যাসের ফলে কিছু পিক্সেল রঙ সামান্য পরিবর্তিত হবে, যা নিজেই আউটপুটটিকে অবৈধ করে তোলে। যখন কোনও মূল চিত্র ব্যবহৃত হয় এবং পিক্সেলগুলি বদলানো অঞ্চলগুলিতে সীমাবদ্ধ থাকে, সমস্ত বিকৃতিটি যেখানে ঘটেছিল সেই অঞ্চলে রেখে দেওয়া হয় এবং তারপরে চিত্রটি পুনঃস্থাপনের পরে সেই অঞ্চল জুড়ে সমানভাবে ছড়িয়ে পড়ে। অঞ্চলগুলির মধ্যে গড় বিকৃতির পার্থক্য তাদের মধ্যে একটি দৃশ্যমান পার্থক্য ছেড়ে দেয়, সুতরাং স্ক্র্যাম্বলিং প্রক্রিয়াতে ব্যবহৃত অঞ্চলগুলি পুনরুদ্ধার করা চিত্রটিতে দৃশ্যমান।

স্ক্র্যাম্বলিংয়ের আগে .png (বা কোনও ক্ষতিকারক বিন্যাস) এ রূপান্তর করা নিশ্চিত করে যে আনস্র্যাম্বলড চিত্রটি কোনও পোড়া বা বিকৃতি ছাড়াই মূলটির সাথে সমান:

কোন পোড়া সঙ্গে png

সামান্য বিশদ

  • অঞ্চলগুলিতে সর্বনিম্ন আকার 256 পিক্সেল চাপানো হয়। যদি চিত্রটি খুব ছোট অঞ্চলে বিভক্ত হওয়ার অনুমতি দেওয়া হয়, তবে মূল চিত্রটি স্ক্র্যাম্বলিংয়ের পরেও আংশিকভাবে দৃশ্যমান হবে।
  • বিজোড় সংখ্যার পিক্সেলের সাথে একাধিক অঞ্চল যদি থাকে তবে দ্বিতীয় অঞ্চল থেকে এক পিক্সেল প্রথমটিতে পুনরায় নিয়োগ করা হয়, ইত্যাদি so এর অর্থ এমন এক পিক্সেল বিশিষ্ট সংখ্যার সাথে কেবল এক অঞ্চলই থাকতে পারে এবং কেবলমাত্র একটি পিক্সেলই আনস্র্যাম্বলড থাকবে।
  • তৃতীয় alচ্ছিক যুক্তি রয়েছে যা অঞ্চলগুলির সংখ্যা সীমাবদ্ধ করে। উদাহরণস্বরূপ এটিকে 2 এ সেট করা দুটি টোন স্ক্র্যাম্বলড চিত্র দেবে। এটি জড়িত চিত্রগুলির উপর নির্ভর করে আরও ভাল বা খারাপ দেখতে পারে। যদি এখানে একটি নম্বর নির্দিষ্ট করা থাকে তবে চিত্রটি আবার একই নম্বর ব্যবহার করে পুনরুদ্ধার করা যাবে।
  • মূল চিত্রটিতে স্বতন্ত্র রঙের সংখ্যাও অঞ্চলগুলির সংখ্যা সীমিত করে। মূল চিত্রটি যদি দুটি স্বর হয় তবে মূল চিত্র বা তৃতীয় যুক্তি নির্বিশেষে কেবলমাত্র সর্বোচ্চ 2 টি অঞ্চল থাকতে পারে।

2
+1 করতালি! আমি অস্পষ্টভাবে এ সম্পর্কে চিন্তাভাবনা করেছি, তবে এটি কার্যকর করা খুব কঠিন বলে মনে হয়েছিল।
edc65

1
এটা অসাধারণ. আমি একটি এন্ট্রি জমা পেয়েছি, তবে মূল চিত্র বৈশিষ্ট্যের কারণে আমি আপনাকে আরও ভাল পছন্দ করি।
টড লেহম্যান

কি এই দুটি ইমেজ মত বিরুদ্ধে একে অপরের অস্থির চেহারা আমি জানতে আগ্রহী হতে চাই lardlad.com/assets/wallpaper/simpsons1920.jpg এবং blogs.nd.edu/oblation/files/2013/09/BreakingBad.jpg (720x450 করার downsized বা যাই হোক না কেন তা বোঝায়, এবং অবশ্যই জেপিজি বার্ন এড়াতে পিএনজিতে প্রাক রূপান্তরিত)।
টড লেহম্যান

2
@ টডলেহম্যান আমার অ্যালগরিদম এর নিজস্ব বিপরীতমুখী হওয়ার প্রয়োজনের দ্বারা সীমাবদ্ধ। অন্য চিত্রের সাথে সাদৃশ্যপূর্ণ হওয়ার জন্য যদি আপনি কোনও চিত্রটি বদলে ফেলার কিছু সত্যই আকর্ষণীয় পন্থা দেখতে চান তবে আপনার মোনা লিসার প্যালেটে আমেরিকান গথিকের দিকে নজর দেওয়া উচিত । এই প্রোগ্রামগুলির মধ্যে কয়েকটি আপনার উল্লেখ করা চিত্রগুলি দিয়ে আশ্চর্যজনক কাজ করবে।
ট্রাইকোপল্যাক্স

2
মূল চিত্র বৈশিষ্ট্যটি এই মাথা এবং কাঁধকে বিশ্রামের উপরে রাখে।
জ্যাক এইডলি

33

পরিবর্তনের জন্য এখানে একটি অ-র্যান্ডম রূপান্তর

  1. বামদিকে সমস্ত এমনকি কলামগুলি ডানদিকে রাখুন।
  2. পুনরাবৃত্তি nxবার
  3. সারি nyবার জন্য একই কাজ

রূপান্তরটি প্রায় স্ব-বিপরীত, রূপান্তরটি মোট size_xবার বার করা হয় (এক্স-দিকনির্দেশে) আসল চিত্রটি দেয়। আমি সঠিক গণিতটি বের করতে পারি নি, তবে পূর্ণসংখ্যার int(log_2(size_x))বহুগুণ ব্যবহার করে ক্ষুদ্রতম ভুতের চিত্রগুলির সাথে সর্বোত্তম বদলানো হয়

বদলে যাওয়া পাহাড় এখানে চিত্র বর্ণনা লিখুন

from numpy import *
from pylab import imread, imsave

def imshuffle(im, nx=0, ny=0):
    for i in range(nx):
        im = concatenate((im[:,0::2], im[:,1::2]), axis=1)
    for i in range(ny):
        im = concatenate((im[0::2,:], im[1::2,:]), axis=0)
    return im

im1 = imread('circles.png')
im2 = imread('mountain.jpg')

imsave('s_circles.png', imshuffle(im1, 7,7))
imsave('s_mountain.jpg', imshuffle(im2, 8,9))

20 টি পুনরাবৃত্তির মতো প্রথম ধাপগুলি এইভাবে দেখায় (এনএক্স = এন, বিভিন্ন রেজোলিউশনের প্রভাব নোট করুন) এখানে চিত্র বর্ণনা লিখুন


7
এটি সত্যিই দুর্দান্ত একটি অ্যালগরিদম। এবং লেনা শেডারবার্গ ছবিটি ব্যবহার করার জন্য আপনার পুরোপুরি বোনাস পাওয়া উচিত। :)
টড লেহম্যান

সর্বদা লেনাকে

24

ম্যাথামেটিকাল

এই বেশ সহজ. আমি 5 * nPixelsএলোমেলো স্থানাঙ্ক জোড়া এবং সেই দুটি পিক্সেল (যা চিত্রটিকে পুরোপুরি অস্পষ্ট করে তোলে) অদলবদল করি। এটি আনস্র্যাম্বল করতে আমি বিপরীতে একই কাজ করি। অবশ্যই, উভয় পদক্ষেপে একই স্থানাঙ্ক জোড়া পেতে আমার পিআরএনজি বীজ করা দরকার।

scramble[image_] := Module[
   {data, h, w, temp},
   data = ImageData@image;
   {h, w} = Most@Dimensions@data;
   SeedRandom[42];
   (
      temp = data[[#[[1]], #[[2]]]];
      data[[#[[1]], #[[2]]]] = data[[#2[[1]], #2[[2]]]];
      data[[#2[[1]], #2[[2]]]] = temp;
      ) & @@@
    Partition[
     Transpose@{RandomInteger[h - 1, 10*h*w] + 1, 
       RandomInteger[w - 1, 10*h*w] + 1}, 2];
   Image@data
   ];
unscramble[image_] := Module[
   {data, h, w, temp},
   data = ImageData@image;
   {h, w} = Most@Dimensions@data;
   SeedRandom[42];
   (
      temp = data[[#[[1]], #[[2]]]];
      data[[#[[1]], #[[2]]]] = data[[#2[[1]], #2[[2]]]];
      data[[#2[[1]], #2[[2]]]] = temp;
      ) & @@@
    Reverse@
     Partition[
      Transpose@{RandomInteger[h - 1, 10*h*w] + 1, 
        RandomInteger[w - 1, 10*h*w] + 1}, 2];
   Image@data
   ];

দুটি ফাংশন মধ্যে একমাত্র পার্থক্য হল Reverse@মধ্যে unscramble। উভয় ফাংশন একটি আসল চিত্র অবজেক্ট গ্রহণ করে। আপনি সেগুলি নিম্নলিখিত হিসাবে ব্যবহার করতে পারেন:

in = Import["D:\\Development\\CodeGolf\\image-scrambler\\circles.png"]
scr = scramble[im]
out = unscramble[scr]

outএবং inঅভিন্ন। scrদেখতে দেখতে যা এখানে :

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


4
গ্রেট! কেবল সমস্যাটি হ'ল নিজেকে পিআরএনজি তৈরি করা আরও সুরক্ষিত, কারণ কিছু সময়ের পরে যদি ম্যাথামেটিকা ​​পিআরএনজি অ্যালগরিদম পরিবর্তন করতে চায় তবে এটি পুরানো এনকোডযুক্ত চিত্রগুলি ডিকোড করবে না!
সোমনিয়াম

1
খুশী হলাম। পারমুট এবং ফাইন্ডার্পিউউটেশন সহ আপনার একই ফলাফল অর্জন করতে সক্ষম হওয়া উচিত।
ডেভিডসি

আমি নিশ্চিত নই যে আমি বুঝেছি. চক্রের তালিকা হিসাবে আপনি যে যথাযথ অনুমতি চান তা প্রবেশ করতে পারেন।
ডেভিডসি

@ ডেভিডকারেরার এইচএম, আকর্ষণীয়। FindPermutationযদিও আমি ব্যবহারের জন্য মূল অনুমানটি মনে রাখবেন না ?
মার্টিন ইন্ডার

বা কিছু হিসাবে {c, a, b}[[{2, 3, 1}]]ব্যবহার করা যেতে পারে?
সোমনিয়াম

22

সি # (প্রতিসম অ্যালগোরিদমের জন্য বোনাস)

এটি xএরূপ কোনও সন্ধান করে x^2 == 1 mod (number of pixels in image)এবং তারপরে প্রতিটি নতুন পিক্সেল সূচককে xএর নতুন অবস্থান সন্ধান করার দ্বারা কাজ করে। এটি আপনাকে চিত্রটি স্ক্র্যাম্ব করতে এবং আনস্র্যাম্বল করতে সঠিক একই অ্যালগরিদম ব্যবহার করতে দেয়।

using System.Drawing;
using System.IO;
using System.Numerics;

namespace RearrangePixels
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var arg in args)
                ScrambleUnscramble(arg);
        }

        static void ScrambleUnscramble(string fileName)
        {
            using (var origImage = new Bitmap(fileName))
            using (var newImage = new Bitmap(origImage))
            {
                BigInteger totalPixels = origImage.Width * origImage.Height;
                BigInteger modSquare = GetSquareRootOf1(totalPixels);
                for (var x = 0; x < origImage.Width; x++)
                {
                    for (var y = 0; y < origImage.Height; y++)
                    {
                        var newNum = modSquare * GetPixelNumber(new Point(x, y), origImage.Size) % totalPixels;
                        var newPoint = GetPoint(newNum, origImage.Size);
                        newImage.SetPixel(newPoint.X, newPoint.Y, origImage.GetPixel(x, y));
                    }
                }
                newImage.Save("scrambled-" + Path.GetFileName(fileName));
            }
        }

        static BigInteger GetPixelNumber(Point point, Size totalSize)
        {
            return totalSize.Width * point.Y + point.X;
        }

        static Point GetPoint(BigInteger pixelNumber, Size totalSize)
        {
            return new Point((int)(pixelNumber % totalSize.Width), (int)(pixelNumber / totalSize.Width));
        }

        static BigInteger GetSquareRootOf1(BigInteger modulo)
        {
            for (var i = (BigInteger)2; i < modulo - 1; i++)
            {
                if ((i * i) % modulo == 1)
                    return i;
            }
            return modulo - 1;
        }
    }
}

প্রথম পরীক্ষার চিত্র, স্ক্যাম্বলড

দ্বিতীয় পরীক্ষার চিত্র, স্ক্যাম্বলড


1
চতুর এক) alwaysক্যবদ্ধ সমীকরণের সর্বদা সমাধান হবে?
সোমনিয়াম

1
@ ব্যবহারকারী 2992539 সর্বদা তুচ্ছ সমাধান, 1(মূল চিত্র) এবং modulo-1(উল্টানো / বিপরীত চিত্র) থাকবে। বেশিরভাগ সংখ্যার তুচ্ছ সমাধান পাওয়া যায়, তবে কিছু ব্যতিক্রম রয়েছে বলে মনে হয় । (এর প্রাথমিক গুণাবলী সম্পর্কিত modulo)
টিম এস

আমি যেমন বুঝতে পারি তুচ্ছ সমাধান ইমেজটিকে ইনপুটটির মতো করে নিয়ে যায়।
সোমনিয়াম

সঠিক: 1মূল চিত্রটি আউটপুট করে এবং -1ফলাফলগুলি যেমন imgur.com/EiE6VW2
টিম এস

19

সি #, স্ব-বিপরীত, কোনও এলোমেলো নয়

যদি মূল চিত্রটির দুটি মাত্রার মাত্রা থাকে তবে প্রতিটি সারি এবং কলামটি সারি এবং কলামের সাথে বিপরীত বিট প্যাটার্নের সাথে বিনিময় হয়, উদাহরণস্বরূপ 256 প্রস্থের চিত্রের জন্য সারি 0xB4 সারি 0x2D এর সাথে বিনিময় করা হয়। অন্যান্য আকারের চিত্রগুলি 2 টির শক্তির সাথে আয়তক্ষেত্রগুলিতে বিভক্ত হয়।

namespace CodeGolf
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var arg in args)
                Scramble(arg);
        }

        static void Scramble(string fileName)
        {
            using (var origImage = new System.Drawing.Bitmap(fileName))
            using (var tmpImage = new System.Drawing.Bitmap(origImage))
            {
                {
                    int x = origImage.Width;
                    while (x > 0) {
                       int xbit = x & -x;
                        do {
                            x--;
                            var xalt = BitReverse(x, xbit);
                            for (int y = 0; y < origImage.Height; y++)
                                tmpImage.SetPixel(xalt, y, origImage.GetPixel(x, y));
                        } while ((x & (xbit - 1)) != 0);
                    }
                }
                {
                    int y = origImage.Height;
                    while (y > 0) {
                        int ybit = y & -y;
                        do {
                            y--;
                            var yalt = BitReverse(y, ybit);
                            for (int x = 0; x < origImage.Width; x++)
                                origImage.SetPixel(x, yalt, tmpImage.GetPixel(x, y));
                        } while ((y & (ybit - 1)) != 0);
                    } 
                }
                origImage.Save(System.IO.Path.GetFileNameWithoutExtension(fileName) + "-scrambled.png");
            }
        }

        static int BitReverse(int n, int bit)
        {
            if (bit < 4)
                return n;
            int r = n & ~(bit - 1);
            int tmp = 1;
            while (bit > 1) {
                bit >>= 1;
                if ((n & bit) != 0)
                    r |= tmp;
                tmp <<= 1;
            }
            return r;
        }
    }
}

প্রথম চিত্র:

স্ক্র্যাম্বলড প্রথম চিত্র

দ্বিতীয় চিত্র:

স্ক্র্যাম্বলড দ্বিতীয় চিত্র


2
আমি এটিতে "প্লিড" আউটপুটটি পছন্দ করি।
ব্রায়ান রজার্স

14

সি শার্প

স্ক্র্যাম্বলিং এবং আনস্র্যাম্বলিংয়ের একই পদ্ধতি। আমি এটি উন্নত করার জন্য পরামর্শ প্রশংসা করব।

using System;
using System.Drawing;
using System.Linq;

public class Program
{
    public static Bitmap Scramble(Bitmap bmp)
    {
        var res = new Bitmap(bmp);
        var r = new Random(1);

        // Making lists of even and odd numbers and shuffling them
        // They contain numbers between 0 and picture.Width (or picture.Height)
        var rX = Enumerable.Range(0, bmp.Width / 2).Select(x => x * 2).OrderBy(x => r.Next()).ToList();
        var rrX = rX.Select(x => x + 1).OrderBy(x => r.Next()).ToList();
        var rY = Enumerable.Range(0, bmp.Height / 2).Select(x => x * 2).OrderBy(x => r.Next()).ToList();
        var rrY = rY.Select(x => x + 1).OrderBy(x => r.Next()).ToList();

        for (int y = 0; y < bmp.Height; y++)
        {
            for (int x = 0; x < rX.Count; x++)
            {
                // Swapping pixels in a row using lists rX and rrX
                res.SetPixel(rrX[x], y, bmp.GetPixel(rX[x], y));
                res.SetPixel(rX[x], y, bmp.GetPixel(rrX[x], y));
            }
        }
        for (int x = 0; x < bmp.Width; x++)
        {
            for (int y = 0; y < rY.Count; y++)
            {
                // Swapping pixels in a column using sets rY and rrY
                var px = res.GetPixel(x, rrY[y]);
                res.SetPixel(x, rrY[y], res.GetPixel(x, rY[y]));
                res.SetPixel(x, rY[y], px);
            }
        }

        return res;
    }
}

ফলাফল সাইকেডেলিক প্লিডে ফলাফল প্রথমটি দ্বিতীয়


ভালো লাগছে যে এর কিছু স্ট্রিপড প্যাটার্ন রয়েছে)
সোমনিয়াম

1
আপনি কি 2 টি ছবি অদলবদল করতে পারেন? প্রশ্নে পর্বতের চিত্রটি প্রথম is
এএল

1
আপনি কি অ্যালগরিদমের সংক্ষিপ্ত ব্যাখ্যা অন্তর্ভুক্ত করতে পারেন?
ট্রিকোপ্লাক্স

14

পাইথন 2 (স্ব-বিপরীত, কোনও এলোমেলোভাবে নয়, প্রসঙ্গে সংবেদনশীল)

এটি "কমপক্ষে স্বীকৃত" জন্য কোনও পুরস্কার জিতবে না, তবে এটি "আকর্ষণীয়" হিসাবে স্কোর করতে পারে। :-)

আমি প্রসঙ্গে সংবেদনশীল কিছু তৈরি করতে চেয়েছিলাম, যেখানে পিক্সেলগুলির স্ক্র্যাম্বলিং চিত্রটি নিজেই নির্ভর করে।

ধারণাটি বেশ সহজ: পিক্সেলের রঙ থেকে প্রাপ্ত কিছু স্বেচ্ছাসেবী মান অনুসারে সমস্ত পিক্সেল বাছাই করুন এবং তারপরে সেই তালিকার প্রথম পিক্সেলের অবস্থানগুলি সর্বশেষের সাথে, দ্বিতীয়টি দ্বিতীয়টি শেষের সাথে এবং এ জাতীয় কিছুগুলিকে স্যুপ করুন।

দুর্ভাগ্যক্রমে এই সাধারণ পদ্ধতির ক্ষেত্রে একই রঙের পিক্সেল নিয়ে সমস্যা রয়েছে, তাই এটিকে স্ব-বিপরীতমুখী করার জন্য আমার প্রোগ্রামটি আরও কিছুটা জটিল হয়ে উঠল ...

from PIL import Image

img = Image.open('1.png', 'r')
pixels = img.load()
size_x, size_y = img.size

def f(colour):
    r,g,b = colour[:3]
    return (abs(r-128)+abs(g-128)+abs(b-128))//128

pixel_list = [(x,y,f(pixels[x,y])) for x in xrange(size_x) for y in xrange(size_y)]
pixel_list.sort(key=lambda x: x[2])
print "sorted"

colours = {}
for p in pixel_list:
    if p[2] in colours:
        colours[p[2]] += 1
    else:
        colours[p[2]] = 1
print "counted"

for n in set(colours.itervalues()):
    pixel_group = [p for p in pixel_list if colours[p[2]]==n]
    N = len(temp_list)
    for p1, p2 in zip(pixel_group[:N//2], pixel_group[-1:-N//2:-1]):
        pixels[p1[0],p1[1]], pixels[p2[0],p2[1]] = pixels[p2[0],p2[1]], pixels[p1[0],p1[1]]
print "swapped"

img.save('1scrambled.png')
print "saved"

এটি ফলাফল: (ABS (R-128) + ABS (ছ-128) + ABS (খ-128)) // 128 (ABS (R-128) + ABS (ছ-128) + ABS (খ-128)) // 128

আপনি হ্যাশ ফাংশন পরিবর্তন করে বেশ আলাদা ফলাফল অর্জন করতে পারেন f:

  • r-g-b:

    আরজিবি

  • r+g/2.**8+b/2.**16:

    R + + ছ / 2। ** 8 + খ / 2। ** 16

  • math.sin(r+g*2**8+b*2**16):

    math.sin (R + + ছ * 2 ** 8 + খ * 2 ** 16)

  • (r+g+b)//600:

    (R + + G + খ) // 600

  • 0:

    0


3
কি দারুন! এই এক মহান !!! চমৎকার কাজ!
টড লেহম্যান

1
এটি এখন পর্যন্ত সবচেয়ে আকর্ষণীয় একটি। ভাল কাজ!
bebe

12

গণিত (+ বোনাস)

এটি রঙিন চ্যানেলগুলিকে ভেঙে দেয় এবং একটি দীর্ঘ তথ্যের তালিকা হিসাবে চিত্রটিকে স্ক্র্যাম্ব করে। ফলাফলটি আরও কম স্বীকৃত স্ক্র্যাম্বলড সংস্করণ কারণ এটির বর্ণের রঙের মূল হিসাবে একইরূপে বিতরণ নেই (যেহেতু সেই ডেটাটিও স্ক্র্যাম্বল হয়েছিল)। এটি দ্বিতীয় স্ক্যাম্বলড চিত্রটিতে সর্বাধিক সুস্পষ্ট, তবে আপনি যদি ঘনিষ্ঠভাবে তাকান তবে আপনি প্রথমটিতেও একই প্রভাব দেখতে পাবেন। ফাংশনটি তার নিজস্ব বিপরীত।

একটি মন্তব্য ছিল যে এটি বৈধ হতে পারে না কারণ এটি চ্যানেল প্রতি স্ক্র্যাম্বল করে। আমি মনে করি এটি হওয়া উচিত, তবে এটি কোনও বড় বিষয় নয়। পুরো পিক্সেল স্ক্যাম্বল করার জন্য প্রয়োজনীয় একমাত্র পরিবর্তন (প্রতি চ্যানেলের পরিবর্তে) এ পরিবর্তন Flatten @ xকরতে হবে Flatten[x, 1]:)

ClearAll @ f;

f @ x_ := 
  With[
    {r = SeedRandom[Times @@ Dimensions @ x], f = Flatten @ x},
    ArrayReshape[
      Permute[f, Cycles @ Partition[RandomSample @ Range @ Length @ f, 2]],
      Dimensions @ x]]

ব্যাখ্যা

একটি ফাংশন সংজ্ঞা দেয় fযা একটি 2-মাত্রিক অ্যারে নেয় x। ফাংশনটি এলোমেলো বীজ হিসাবে চিত্রের মাত্রাগুলির পণ্য ব্যবহার করে এবং তারপরে অ্যারেটিকে 1-মাত্রিক তালিকায় স্থান দেয় f(স্থানীয়ভাবে ছায়াযুক্ত)। তারপরে এটি সেই ফর্মের একটি তালিকা তৈরি করে {1, 2, ... n}যেখানে nদৈর্ঘ্যটি f, এলোমেলোভাবে সেই তালিকাটিকে অনুমতি দেয়, এটিকে 2 টি ভাগে বিভক্ত করে (সুতরাং, উদাহরণস্বরূপ {{1, 2}, {3, 4}, ...}(মাত্রাগুলি দুটি বিজোড় হলে শেষ সংখ্যাটি বাদ দেওয়া)) এবং তারপরে মানগুলি অদলবদলের fমাধ্যমে অনুমতি দেয় প্রতিটি উপ-তালিকায় সুনির্দিষ্ট অবস্থানগুলি স্রেফ তৈরি হয়েছে এবং শেষ পর্যন্ত এটি অনুমোদিত তালিকাটিকে আবার মূল মাত্রায় ফিরিয়ে দেয় xIt এটি চ্যানেল প্রতি স্ক্র্যামবাল করে কারণ চিত্রের মাত্রাগুলি ভেঙে যাওয়ার পাশাপাশিFlattenকমান্ড প্রতিটি পিক্সেলের চ্যানেল ডেটা ভেঙে দেয়। ফাংশনটি তার নিজস্ব বিপরীতমুখী কারণ চক্রগুলিতে প্রতিটিতে কেবল দুটি পিক্সেল অন্তর্ভুক্ত থাকে।

ব্যবহার

img1=Import@"http://i.stack.imgur.com/2C2TY.jpg"//ImageData;
img2=Import@"http://i.stack.imgur.com/B5TbK.png"//ImageData;

f @ img1 // Image

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

f @ f @ img1 // Image

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

f @ img2 // Image

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

f @ f @ img2 // Image

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

এখানে ব্যবহার করা হয় Flatten[x, 1]

g@x_ := With[{r = SeedRandom[Times @@ Dimensions @ x], f = Flatten[x, 1]}, 
  ArrayReshape[
   Permute[f, Cycles@Partition[RandomSample@Range@Length@f, 2]], 
   Dimensions@x]]

g@img2 // Image

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


1
আমার অনুমান যে এটি মানদণ্ডগুলি পূরণ করে না, যেহেতু এটি পিক্সেল স্কেলের চেয়ে ছোট আকারের হয়ে যায়।
ট্রাইকোপল্যাক্স

1
আমি এটি একটি বৈধ উত্তর বলে মনে করি না, তবে আমি এটি সত্যিই পছন্দ করি। এটি একটি আকর্ষণীয় মোড়, সুতরাং যাইহোক +1 ...
ট্রাইকোপল্যাক্স

1
@githubphagocyte আপডেট দেখুন :)
এমফভনহ

দুর্দান্ত - আমি আবার +1 এ পৌঁছেছি তবে অবশ্যই আমি এটি দু'বার করতে পারি না ...
ট্রাইকপ্লেক্স

1
@ গিথুবাগগোসাইট ওহ ঠিক আছে, আমি ভুলে গেছি সংক্ষিপ্ত বাক্য গঠনটি উদ্ভট হতে পারে। হ্যাঁ. f @ f @ img1 // Image(সম্পূর্ণ বাক্য Image[f[f[img1]]]
বাক্সে

10

মতলব (+ বোনাস)

আমি মূলত এলোমেলোভাবে দুটি পিক্সেলের অবস্থান পরিবর্তন করে এবং প্রতিটি পিক্সেল যা স্যুইচ করা হয়েছে তা ট্যাগ করি যাতে এটি আর স্যুইচ হবে না। একই স্ক্রিপ্টটি আবার 'ডিক্রিপশন' এর জন্য ব্যবহার করা যেতে পারে কারণ আমি প্রতিবার এলোমেলো নম্বর জেনারেটরটিকে পুনরায় সেট করি। এটি প্রায় সমস্ত পিক্সেল স্যুইচ করা অবধি করা হয়ে থাকে (তবে ধাপের আকার 2 এর চেয়ে বড় কেন)

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

চিত্র

1 2

কোড

img = imread('shuffle_image2.bmp');
s = size(img)
rand('seed',0)
map = zeros(s(1),s(2));
for i = 1:2.1:s(1)*s(2) %can use much time if stepsize is 2 since then every pixel has to be exchanged
    while true %find two unswitched pixels
        a = floor(rand(1,2) .* [s(1),s(2)] + [1,1]);
        b = floor(rand(1,2) .* [s(1),s(2)] + [1,1]);
        if map(a(1),a(2)) == 0 && map(b(1),b(2)) == 0
            break
        end
    end
    %switch
    map(a(1),a(2)) = 1;
    map(b(1),b(2)) = 1;
    t = img(a(1),a(2),:);
    img(a(1),a(2),:) = img(b(1),b(2),:);
    img(b(1),b(2),:) = t;
end
image(img)
imwrite(img,'output2.png')

আমি পুরোপুরি বুঝতে পারি না, আপনার কোডটি এনক্রিপ্ট হওয়া চিত্রের উপর দ্বিতীয়বার প্রয়োগ করা হলে এটি ডিক্রিপ্ট হবে?
সোমনিয়াম

2
ঠিক: প্রতিটি সময় ঠিক দুটি পিক্সেল অদলবদল হয়ে যায়, এবং পুরো প্রক্রিয়া চলাকালীন আবার অদলবদল হবে না। কারণ 'এলোমেলো' সংখ্যা দুটি একইরকম (এলোমেলো সংখ্যার জেনারেটরটি পুনরায় সেট করার কারণে), পিক্সেল জোড়া আবার অদলবদল হয়ে যাবে। (
আরএনজি

1
হা, যে ছিল আসলে আমার প্রাথমিক ধারণা, কিন্তু তারপর আমি, নিশ্চিত করুন প্রতিটি পিক্সেল ঠিক একবার আনা হয় না বিরক্ত না হওয়ার কারণে আমি কাজ পেতে ছিল। : ডি +1!
মার্টিন ইন্ডার

3
@ user2992539 ওয়েল খুঁজে বার করো অক্টেভ যা মতলব জন্য একটি চমৎকার ওপেনসোর্স বিকল্প নেই, এবং আপনি অষ্টক সরাসরি মতলব কোডের 99% রান করতে পারেন।
flawr

2
আমি মনে করি আপনি যদি নিজের ছবিতে সত্যই শক্ত করে যান তবে আপনি ইনপুট থেকে কিছু কাঠামো দেখতে পাচ্ছেন (যা সমস্ত পিক্সেল না সরানোর কারণে)। আমার ধারণা আপনি যদি নিজের নির্বাচনের অ্যালগরিদমকে ও (∞) এর পরিবর্তে ও (1) এ চালানোর জন্য পরিবর্তন করেন তবে আপনি এটি ঠিক করতে পারেন। ;)
মার্টিন ইন্ডার

10

ম্যাথমেটিকা ​​- স্ক্র্যাম্ব করার জন্য একটি ক্রমশক্তি ব্যবহার করুন এবং এর বিপরীতকে ছাঁটাই থেকে যায়।

একটি jpg চিত্র {r,g,b}পিক্সেল রঙের একটি ত্রি-মাত্রিক অ্যারে । (3 টি মাত্রা সারি, কলাম এবং রঙ অনুসারে পিক্সেলের সেট গঠন করে)। এটি {r,g,b}ত্রিগুজের একটি তালিকাতে সমতল করা যেতে পারে , তারপরে "পরিচিত" চক্রের তালিকা অনুসারে অনুমতি দেওয়া হয় এবং শেষ পর্যন্ত মূল মাত্রাগুলির একটি অ্যারেতে পুনরায় একত্রিত হয়। ফলাফলটি একটি স্ক্যাম্বলড চিত্র is

আনস্র্যাম্বলিং স্ক্র্যাম্বলড ইমেজ নেয় এবং চক্র তালিকার বিপরীতে এটি প্রক্রিয়া করে। এটি আউটপুট করে, হ্যাঁ, মূল চিত্রটি।

সুতরাং একটি একক ফাংশন (বর্তমান ক্ষেত্রে scramble) স্ক্র্যাম্বলিংয়ের পাশাপাশি একটি চিত্রে আনস্র্যাম্বলিং পিক্সেল হিসাবে কাজ করে।

কোনও চিত্র বীজ সংখ্যার সাথে ইনপুট থাকে (তা নিশ্চিত করার জন্য যে এলোমেলো নম্বর জেনারেটর স্ক্র্যাম্বলিং এবং আনস্র্যাম্বলিংয়ের জন্য একই অবস্থায় থাকবে)। প্যারামিটার, বিপরীত, মিথ্যা হলে, ফাংশনটি স্ক্র্যাম্ব হবে। এটি সত্য হলে, ফাংশনটি ছাঁটাই হবে।


হামাগুড়ি দিয়া আরোহণ

পিক্সেল সমতল এবং চক্রের একটি এলোমেলো তালিকা তৈরি করা হয়। পারমুট চ্যাপ্টা তালিকায় পিক্সেলগুলির অবস্থান পরিবর্তন করতে চক্র ব্যবহার করে।

জট ছাড়ানো

একই ফাংশন, scrambleunscrambling জন্য ব্যবহৃত হয়। তবে চক্র তালিকার ক্রমটি বিপরীত।

scramble[img_,s_,reverse_:False,imgSize_:300]:=
  Module[{i=ImageData[img],input,r},input=Flatten[i,1];SeedRandom[s];
  r=RandomSample@Range[Length[input]];Image[ArrayReshape[Permute[input,
  Cycles[{Evaluate@If[reverse,Reverse@r,r]}]],Dimensions[i]],ImageSize->imgSize]]

উদাহরণ

একই বীজ (37) স্ক্র্যাম্বলিং এবং আনস্র্যাম্বলিংয়ের জন্য ব্যবহৃত হয়।

এটি পর্বতের স্ক্র্যাম্বলড চিত্র তৈরি করে। নীচের চিত্রটি দেখায় যে পরিবর্তনশীল স্ক্র্যাম্বলড মাউন্টটি পর্বতের দৃশ্যের আসল চিত্র দ্বারা প্রতিস্থাপিত হতে পারে।

scrambledMount=scramble[mountain, 37, True]

mount1


এখন আমরা বিপরীত চালাচ্ছি; স্ক্র্যাম্বলড মাউন্ট প্রবেশ করা হয় এবং আসল চিত্রটি পুনরুদ্ধার করা হয়।

 scramble[scrambledMount, 37, True]

mount2


চেনাশোনাগুলির জন্য একই জিনিস:

circles1


 scramble[scrambledCircles, 37, True]

circles2


আমি দেখতে পাচ্ছি না যে কোনও চিত্র 3 ত্রিমাত্রিক অ্যারে হতে পারে।
edc65

1
@ edc65, সারি এক্স কলাম x রং। পাহাড়ের চিত্রটি 3 টি বর্ণ দ্বারা 800 কলাম দ্বারা 422 সারি। যদি অ্যারের সমতল হয়, তবে এটি এক মাত্রিক অ্যারে হিসাবে 1012800 টুকরো ডেটা দেয়, যেমন একটি তালিকা হিসাবে।
ডেভিডসি

@ edc65 আমার যুক্ত করা উচিত যে রঙগুলি আরজিবি ট্রিপল হিসাবে পুনরায় সাজানোর জন্য পারমুট ব্যবহার করা হয়েছিল। আমি আর এটি ফ্ল্যাট করিনি কারণ আমি কোনও পিক্সেলের রঙের তালিকার মধ্যে কোনও পরিবর্তন আনতে আগ্রহী নই। আপনি যদি উপাদান হিসাবে rgb তথ্য, {r, g, b consider বিবেচনা করে থাকেন তবে আমরা একটি 2D অ্যারে নিয়ে কথা বলছি। এইভাবে দেখা হয়েছে, আপনি উত্থাপিত প্রশ্নটি উত্থাপন করে (কোন চিত্রটি 3 ত্রিমাত্রিক অ্যারে কীভাবে হতে পারে?) উত্থাপন করা সম্পূর্ণ অর্থবোধ করে। আসলে, আরজিবি উপাদানগুলি অন্য একটি মাত্রা যুক্ত করে এই বিষয়টিকে উপেক্ষা করে কোনও চিত্রকে 2 ডি অ্যারে হিসাবে বিবেচনা করা আরও স্বাভাবিক হতে পারে।
ডেভিডসি

10

পাইথন

আমি এই ধাঁধাটি পছন্দ করি, তাকে আকর্ষণীয় মনে হয়েছিল এবং আমি চিত্রটিতে প্রয়োগ করার জন্য একটি মোড়ানো এবং আন্দোলনের ফাংশন নিয়ে এসেছি।

Wraped

আমি ছবিটি পাঠ্য হিসাবে পড়েছি (বাম থেকে ডানে, উপরে এবং নীচে) এবং এটিকে শামুক শেল হিসাবে লিখি।

এই ফাংশনটি চক্রাকার: এখানে এন, ফ ^ (এন) (এক্স) = এক্স রয়েছে, উদাহরণস্বরূপ, 4 * 2 এর একটি ছবির জন্য, চ (চ (চ (চ (এক্স))) = x

আন্দোলন

আমি একটি এলোমেলো সংখ্যা নিয়েছি এবং এটি থেকে প্রতিটি কলাম এবং লিগন সরিয়ে নিয়েছি

কোড

# Opening and creating pictures
img = Image.open("/home/faquarl/Bureau/unnamed.png")
PM1 = img.load()
(w,h) = img.size
img2 = Image.new( 'RGBA', (w,h), "black") 
PM2 = img2.load()
img3 = Image.new( 'RGBA', (w,h), "black") 
PM3 = img3.load()

# Rotation
k = 0
_i=w-1
_j=h-1
_currentColMin = 0
_currentColMax = w-1
_currentLigMin = 0
_currentLigMax = h-1
_etat = 0
for i in range(w):
    for j in range(h):
        PM2[_i,_j]=PM1[i,j]
        if _etat==0:
            if _currentColMax == _currentColMin:
                _j -= 1
                _etat = 2
            else:
                _etat = 1
                _i -= 1
        elif _etat==1:
            _i -= 1
            if _j == _currentLigMax and _i == _currentColMin:
                _etat = 2
        elif _etat==2:
            _j -= 1
            _currentLigMax -= 1
            if _j == _currentLigMin and _i == _currentColMin:
                _etat = 5
            else:
                _etat = 3
        elif _etat==3:
            _j -= 1
            if _j == _currentLigMin and _i == _currentColMin:
                _etat = 4
        elif _etat==4:
            _i += 1
            _currentColMin += 1
            if _j == _currentLigMin and _i == _currentColMax:
                _etat = 7
            else:
                _etat = 5
        elif _etat==5:
            _i += 1
            if _j == _currentLigMin and _i == _currentColMax:
                _etat = 6
        elif _etat==6:
            _j += 1
            _currentLigMin += 1
            if _j == _currentLigMax and _i == _currentColMax:
                _etat = 1
            else:
                _etat = 7
        elif _etat==7:
            _j += 1
            if _j == _currentLigMax and _i == _currentColMax:
                _etat = 8
        elif _etat==8:
            _i -= 1
            _currentColMax -= 1
            if _j == _currentLigMax and _i == _currentColMin:
                _etat = 3
            else:
                _etat = 1
        k += 1
        if k == w * h:
            i = w
            j = h
# Movement
if w>h:z=w
else:z=h
rand.seed(z)
a=rand.randint(0,h)
for i in range(w):
  for j in range(h):
  if i%2==0:
    PM3[(i+a)%w,(j+a)%h]=PM2[i,j]
  else:
    PM3[(i-a)%w,(j-a)%h]=PM2[i,j]
# Rotate Again

ছবি

প্রথম আবর্তন: এখানে চিত্র বর্ণনা লিখুন

তারপরে আদেশ এখানে চিত্র বর্ণনা লিখুন

এবং শেষ রোটোশন সহ: এখানে চিত্র বর্ণনা লিখুন

অন্য উদাহরণ হিসাবে: এখানে চিত্র বর্ণনা লিখুন


2
আপনি কিভাবে মূল চিত্রটি পুনরুদ্ধার করবেন?
ট্রাইকোপল্যাক্স

যদি এটি কেবল ঘূর্ণন হয় তবে আমি এটি একটি নির্দিষ্ট সময় (আকারের উপর নির্ভর করে) করতে পারি। যাইহোক, যদি আমার অনুমতিগুলি থাকে তবে আমি নিশ্চিত নই যে এটি চক্রযুক্ত কিনা তাই আমার কেবল একটি দ্বিতীয় ফাংশন রয়েছে যা কেবলমাত্র পিএম 2 [_আই, _জে] = পিএম 1 [আই, জে] পিএম 2 হয়ে গেছে [i, j] = PM1 [ _আই, _ জ] এবং পিএম 3 [(আই + এ)% ডাব্লু, (জে + এ)% এইচ] = পিএম 2 [আই, জে] পিএম 3 হয়ে গেছে [(আইএ)% ডাব্লু, (জাএ)% এইচ] = পিএম 2 [আমি, ঞ]। এই দুটি লাইন চ্যাং ছাড়াই এটি করার জন্য আমি সন্ধান করছি
ফ্যাকোরেল

8

ভিবি.এনইটি (+ বোনাস)

এটি flawr এর ধারণা ব্যবহার করে, তাকে ধন্যবাদ, তবে এটি বিভিন্ন অদলবদল এবং চেক অ্যালগরিদম ব্যবহার করে। প্রোগ্রামটি একইভাবে এনকোড করে এবং ডিকোড করে।

Imports System

Module Module1

    Sub swap(ByVal b As Drawing.Bitmap, ByVal i As Integer, ByVal j As Integer)
        Dim c1 As Drawing.Color = b.GetPixel(i Mod b.Width, i \ b.Width)
        Dim c2 As Drawing.Color = b.GetPixel(j Mod b.Width, j \ b.Width)
        b.SetPixel(i Mod b.Width, i \ b.Width, c2)
        b.SetPixel(j Mod b.Width, j \ b.Width, c1)
    End Sub

    Sub Main(ByVal args() As String)
        For Each a In args
            Dim f As New IO.FileStream(a, IO.FileMode.Open)
            Dim b As New Drawing.Bitmap(f)
            f.Close()
            Dim sz As Integer = b.Width * b.Height - 1
            Dim w(sz) As Boolean
            Dim r As New Random(666)
            Dim u As Integer, j As Integer = 0
            Do While j < sz
                Do
                    u = r.Next(0, sz)
                Loop While w(u)
                ' swap
                swap(b, j, u)
                w(j) = True
                w(u) = True
                Do
                    j += 1
                Loop While j < sz AndAlso w(j)
            Loop
            b.Save(IO.Path.ChangeExtension(a, "png"), Drawing.Imaging.ImageFormat.Png)
            Console.WriteLine("Done!")
        Next
    End Sub

End Module

আউটপুট চিত্রগুলি:


8

এটি পিক্সেলগুলিকে অদলবদল করতে এবং এগুলি পরিবর্তন না করার বিষয়ে মনে করিয়ে দেওয়ার পরে, এখানে এর সমাধান আমার এখানে রয়েছে:

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

ফিরিয়ে আনা হয়েছে: এখানে চিত্র বর্ণনা লিখুন

এটি পিক্সেল অর্ডারটি এলোমেলো করে করা হয়, তবে এটি পুনরুদ্ধার করতে সক্ষম হতে, এলোমেলোকরণ স্থির করা হয়েছে। এটি একটি নির্দিষ্ট বীজের সাথে সিউডো-এলোমেলো ব্যবহার করে এবং সূচিগুলির তালিকা তৈরি করে যা কোন পিক্সেলকে অদলবদল করবে তা বর্ণনা করে। অদলবদল যেমন হবে তেমন একই তালিকাটি মূল চিত্রটি পুনরুদ্ধার করবে।

public class ImageScramble {

  public static void main(String[] args) throws IOException {
    if (args.length < 2) {
      System.err.println("Usage: ImageScramble <fileInput> <fileOutput>");
    } else {
      // load image
      final String extension = args[0].substring(args[0].lastIndexOf('.') + 1);
      final BufferedImage image = ImageIO.read(new File(args[0]));
      final int[] pixels = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth());

      // create randomized swap list
      final ArrayList<Integer> indexes = IntStream.iterate(0, i -> i + 1).limit(pixels.length).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
      Collections.shuffle(indexes, new Random(1337));

      // swap all pixels at index n with pixel at index n+1
      int tmp;
      for (int i = 0; i < indexes.size(); i += 2) {
        tmp = pixels[indexes.get(i)];
        pixels[indexes.get(i)] = pixels[indexes.get(i + 1)];
        pixels[indexes.get(i + 1)] = tmp;
      }

      // write image to disk
      final BufferedImage imageScrambled = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
      imageScrambled.setRGB(0, 0, imageScrambled.getWidth(), imageScrambled.getHeight(), pixels, 0, imageScrambled.getWidth());
      ImageIO.write(imageScrambled, extension, new File(args[1]));
    }
  }
}

নোট করুন যে কোনও অকার্যকর সংকোচনের বিন্যাসে এই অ্যালগরিদম ব্যবহার করা একই ফলাফল তৈরি করবে না, কারণ চিত্র বিন্যাসটি ডেটা পরিবর্তন করবে। এটি পিএনজির মতো কোনও ক্ষয়-হ্রাস কোডেকের সাথে দুর্দান্ত কাজ করা উচিত work


8

ম্যাথামেটিকাল

আমরা একটি সহায়ক ফাংশন hএবং স্ক্র্যাম্বলিং ফাংশনটিকে এইভাবে সংজ্ঞায়িত করি scramble:

h[l_List, n_Integer, k_Integer: 1] := 
  With[{ m = Partition[l, n, n, 1, 0] }, 
    Flatten[
      Riffle[
        RotateLeft[ m[[ ;; , {1} ]] , k ],
        m[[ ;; , 2;; ]]
      ], 1
    ] [[ ;; Length[l] ]]
  ];

scramble[img_Image, k_Integer] :=
  Module[{ list , cNum = 5 },
    Which[
      k > 0,    list = Prime@Range[cNum],
      k < 0,    list = Reverse@Prime@Range[cNum],
      True,     list = {}
    ];
    Image[
      Transpose[
        Fold[ h[ #1, #2, k ] &, #, list ] & /@
        Transpose[
          Fold[ h[#1, #2, k] &, #, list ] & /@ ImageData[img]
        ]
      ]
    ]
  ];

কোনও চিত্র লোড করার পরে, চিত্রটি স্ক্র্যাম্ব করার জন্য আপনি যে কোনও পূর্ণসংখ্যা scramble[img, k]কোথায় kতা কল করতে পারেন । সাথে আবার কল করা -kঅবনমিত হবে। (যদি kতা হয় 0তবে কোনও পরিবর্তন করা হয় না)) সাধারণত kএমন কিছু হতে বেছে নেওয়া উচিত 100যা একটি সুন্দর স্ক্র্যাম্বলড চিত্র দেয়:

উদাহরণ আউটপুট 1

উদাহরণ আউটপুট 2


7

মতলব: সারি / কলামের যোগফলের ভিত্তিতে সারি এবং কলাম স্ক্র্যাম্বলিং

এটি মজাদার ধাঁধার মতো মনে হয়েছিল, তাই আমি এটি সম্পর্কে চিন্তাভাবনা করেছি এবং নীচের ফাংশনটি নিয়ে এসেছি। এটি সার্কুলার শিফটিংয়ের সময় সারি এবং কলাম পিক্সেল-মান সংখ্যার অদম্যতার উপর ভিত্তি করে: এটি প্রতিটি সারি, তারপরে প্রতিটি কলামে, সারি / কলামের পিক্সেল মানগুলির মোট যোগফল (শিফট-ভেরিয়েবলের পুরো সংখ্যার জন্য একটি uint8 ধরে) )। এরপরে প্রতিটি কলামটি তারপরে বিপরীত দিকে তাদের যোগফলের সাথে সারি করে পাল্টানো যায়।

এটি অন্যদের মতো সুন্দর নয়, তবে আমি পছন্দ করি যে এটি নন-এলোমেলো এবং ইমেজ দ্বারা সম্পূর্ণরূপে নির্দিষ্ট - কোনও পছন্দ পরামিতি নেই।

আমি মূলত এটি প্রতিটি রঙের চ্যানেলকে আলাদাভাবে স্থানান্তরিত করার জন্য ডিজাইন করেছি, তবে তারপরে আমি কেবলমাত্র পুরো পিক্সেল সরাতে স্পেসিফিকেশনটি লক্ষ্য করেছি।

function pic_scramble(input_filename)
i1=imread(input_filename);
figure;
subplot(1,3,1);imagesc(i1);title('Original','fontsize',20);

i2=i1;
for v=1:size(i1,1)
    i2(v,:,:)=circshift(i2(v,:,:),sum(sum(i2(v,:,:))),2);
end
for w=1:size(i2,2)
    i2(:,w,:)=circshift(i2(:,w,:),sum(sum(i2(:,w,:))),1);
end
subplot(1,3,2);imagesc(i2);title('Scrambled','fontsize',20);

i3=i2;
for w=1:size(i3,2)
    i3(:,w,:)=circshift(i3(:,w,:),-1*sum(sum(i3(:,w,:))),1);
end
for v=1:size(i3,1)
    i3(v,:,:)=circshift(i3(v,:,:),-1*sum(sum(i3(v,:,:))),2);
end
subplot(1,3,3);imagesc(i3);title('Recovered','fontsize',20);

প্রথম পরীক্ষার চিত্র সেকন্ট পরীক্ষার চিত্র


6

জাভা

এই প্রোগ্রামটি এলোমেলোভাবে পিক্সেলগুলিকে অদলবদল করে (পিক্সেল থেকে পিক্সেল ম্যাপিং তৈরি করে) তবে এলোমেলো ফাংশনের পরিবর্তে এটি ম্যাথ.সিন () (পূর্ণসংখ্যার এক্স) ব্যবহার করে। এটি পুরোপুরি বিপরীতমুখী। পরীক্ষার চিত্রগুলির সাথে এটি কিছু নিদর্শন তৈরি করে।

পরামিতি: পূর্ণসংখ্যা নম্বর (পাসের সংখ্যা, বিপরীতে নেতিবাচক সংখ্যা, 0 কিছুই করে না), ইনপুট ম্যাজ এবং আউটপুট চিত্র (একই হতে পারে)। আউটপুট ফাইলটি বিন্যাসে থাকা উচিত যা ক্ষতবিহীন সংকোচনের ব্যবহার করে।

1 পাস: এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

100 টি পাস (এটি করতে কয়েক মিনিট সময় লাগে): এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

কোড:

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Test{

public static void main(String... args) {
    String in = "image.png";
    String out = in;
    int passes = 0;
    if (args.length < 1) {
        System.out.println("no paramem encryptimg, 1 pass, reading and saving image.png");
        System.out.println("Usage: pass a number. Negative - n passes of decryption, positive - n passes of encryption, 0 - do nothing");
    } else {
        passes = Integer.parseInt(args[0]);
        if (args.length > 1) {
            in = args[1];
        }
        if(args.length > 2){
            out = args[2];
        }
    }
    boolean encrypt = passes > 0;
    passes = Math.abs(passes);
    for (int a = 0; a < passes; a++) {
        BufferedImage img = null;
        try {
            img = ImageIO.read(new File(a == 0 ? in : out));
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        int pixels[][] = new int[img.getWidth()][img.getHeight()];
        int[][] newPixels = new int[img.getWidth()][img.getHeight()];
        for (int x = 0; x < pixels.length; x++) {
            for (int y = 0; y < pixels[x].length; y++) {
                pixels[x][y] = img.getRGB(x, y);
            }
        }
        int amount = img.getWidth() * img.getHeight();
        int[] list = new int[amount];
        for (int i = 0; i < amount; i++) {
            list[i] = i;
        }
        int[] mapping = new int[amount];
        for (int i = amount - 1; i >= 0; i--) {
            int num = (Math.abs((int) (Math.sin(i) * amount))) % (i + 1);
            mapping[i] = list[num];
            list[num] = list[i];
        }
        for (int xz = 0; xz < amount; xz++) {
            int x = xz % img.getWidth();
            int z = xz / img.getWidth();
            int xzMap = mapping[xz];
            int newX = xzMap % img.getWidth();
            int newZ = xzMap / img.getWidth();
            if (encrypt) {
                newPixels[x][z] = pixels[newX][newZ];
            } else {
                newPixels[newX][newZ] = pixels[x][z];
            }
        }
        BufferedImage newImg = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < pixels.length; x++) {
            for (int y = 0; y < pixels[x].length; y++) {
                newImg.setRGB(x, y, newPixels[x][y]);
            }
        }

        try {
            String[] s = out.split("\\.");
            ImageIO.write(newImg, s[s.length - 1],
                    new File(out));
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
    }
}
}

6

পিআইএল সহ পাইথন ২.7

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

ফলাফল বেশ তরত্নিশ।

বিপরীতে, আমরা কেবল এটি বিপরীত ক্রমে করি এবং বিপরীত পরিমাণে স্থানান্তর করি।

কোড

from PIL import Image

def slideColumn (pix, tpix, x, offset, height):
  for y in range(height):
    tpix[x,(offset+y)%height] = pix[x,y]

def slideRow (pix, tpix, y, offset, width):
  for x in range(width):
    tpix[(offset+x)%width,y] = pix[x,y]

def copyPixels (source, destination, width, height):
  for x in range(width):
    for y in range(height):
      destination[x,y]=source[x,y]

def shuffleHorizontal (img, tmpimg, factor, encoding):
  xsize,ysize = img.size
  pix = img.load()
  tpix = tmpimg.load()
  for y in range(ysize):
    offset = y*factor
    if y%2==0:
      offset = xsize-offset
    offset = (xsize + offset) % xsize
    if encoding:
      slideRow(pix,tpix,y,offset,xsize)
    else:
      slideRow(pix,tpix,y,-offset,xsize)
  copyPixels(tpix,pix,xsize,ysize)

def shuffleVertical (img, tmpimg, factor, encoding):
  xsize,ysize = img.size
  pix = img.load()
  tpix = tmpimg.load()
  for x in range(xsize):
    offset = x*factor
    if x%2==0:
      offset = ysize-offset
    offset = (ysize + offset) % ysize
    if encoding:
      slideColumn(pix,tpix,x,offset,ysize)
    else:
      slideColumn(pix,tpix,x,-offset,ysize)
  copyPixels(tpix,pix,xsize,ysize)


def plaidify (img):
  tmpimg = Image.new("RGB",img.size)
  shuffleVertical(img,tmpimg,4,True)
  shuffleHorizontal(img,tmpimg,4,True)

def deplaidify (img):
  tmpimg = Image.new("RGB",img.size)
  shuffleHorizontal(img,tmpimg,4,False)
  shuffleVertical(img,tmpimg,4,False)

ফলাফল

চিত্র 1 থেকে প্লেড:

প্লেডিফায়েড 1.jpg

প্লেড ফর্ম চিত্র 2:

প্লাডিফাইড 2.png


2
খুব সুন্দর! 45 ° কোণে কি তির্যকগুলি পাওয়া সম্ভব?
টড লেহম্যান

2
এটি অফসেট লাইনগুলিতে পরিবর্তিত করে সম্ভব: offset = x*xsize/ysize এবং offset = y*ysize/xsize তবে দুর্ভাগ্যক্রমে এটি চিত্রটিও লুকায় না।
জুনিয়র

5

পাইথন (+ বোনাস) - পিক্সেলগুলির ক্রমবর্ধমান

এই পদ্ধতিতে, প্রতিটি পিক্সেলকে অন্য অবস্থানে স্থাপন করা হবে, অন্য পিক্সেলটি প্রথম অবস্থানে রাখার সীমাবদ্ধতার সাথে। গাণিতিকভাবে, এটি চক্রের দৈর্ঘ্যের 2 সহ একটি অনুচ্ছেদ such যেমন, পদ্ধতিটি এটি নিজস্ব বিপরীত।

পূর্ববর্তী ক্ষেত্রে, এটি এমএফভিওনের সাথে খুব মিল, তবে এই জমাটি পাইথন-এ রয়েছে এবং আমাকে সেই আদেশটি নিজেই তৈরি করতে হয়েছিল।

def scramble(I):
    result = np.zeros_like(I)
    size = I.shape[0:2]
    nb_pixels = size[0]*size[1]
    #Build permutation
    np.random.seed(0)
    random_indices = np.random.permutation( range(nb_pixels) )
    random_indices1 = random_indices[0:int(nb_pixels/2)]
    random_indices2 = random_indices[-1:-1-int(nb_pixels/2):-1]
    for c in range(3):
        Ic = I[:,:,c].flatten()
        Ic[ random_indices2 ] = Ic[random_indices1]
        Ic[ random_indices1 ] = I[:,:,c].flatten()[random_indices2]
        result[:,:,c] = Ic.reshape(size)
    return result

প্রথম পরীক্ষার চিত্র: প্রথম পরীক্ষার চিত্র দ্বিতীয় পরীক্ষার চিত্র: দ্বিতীয় পরীক্ষার চিত্র


5

পাইথন ২.7 + পিআইএল, স্লাইডিং ধাঁধা থেকে অনুপ্রেরণা

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

ফলাফল:

মূল

মূল

গ্রানুলারিটি 16

16

গ্রানুলারিটি 13

13

গ্রানুলারিটি 10

10

গ্রানুলারিটি 3

3

গ্রানুলারিটি 2

2

গ্রানুলারিটি ঘ

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

মূল

মূল

গ্রানুলারিটি 16

16

গ্রানুলারিটি 13

13

গ্রানুলারিটি 10

10

গ্রানুলারিটি 3

3

গ্রানুলারিটি 2

2

গ্রানুলারিটি ঘ

1

কোড:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PIL import Image
import random

def scramble_blocks(im,granularity,password,nshuffle):
    set_seed(password)
    width=im.size[0]
    height=im.size[1]

    block_width=find_block_dim(granularity,width)       #find the possible block dimensions
    block_height=find_block_dim(granularity,height)

    grid_width_dim=width/block_width                #dimension of the grid
    grid_height_dim=height/block_height

    nblocks=grid_width_dim*grid_height_dim          #number of blocks

    print "nblocks: ",nblocks," block width: ",block_width," block height: ",block_height
    print "image width: ",width," image height: ",height
    print "getting all the blocks ..."
    blocks=[]
    for n in xrange(nblocks): #get all the image blocks
        blocks+=[get_block(im,n,block_width,block_height)]

    print "shuffling ..."
    #shuffle the order of the blocks
    new_order=range(nblocks)
    for n in xrange(nshuffle):
        random.shuffle(new_order)

    print "building final image ..."
    new_image=im.copy()
    for n in xrange(nblocks):
        #define the target box where to paste the new block
        i=(n%grid_width_dim)*block_width                #i,j -> upper left point of the target image
        j=(n/grid_width_dim)*block_height
        box = (i,j,i+block_width,j+block_height)    

        #paste it   
        new_image.paste(blocks[new_order[n]],box)

    return new_image



#find the dimension(height or width) according to the desired granularity (a lower granularity small blocks)
def find_block_dim(granularity,dim):
    assert(granularity>0)
    candidate=0
    block_dim=1
    counter=0
    while counter!=granularity:         #while we dont achive the desired granularity
        candidate+=1
        while((dim%candidate)!=0):      
            candidate+=1
            if candidate>dim:
                counter=granularity-1
                break

        if candidate<=dim:
            block_dim=candidate         #save the current feasible lenght

        counter+=1

    assert(dim%block_dim==0 and block_dim<=dim)
    return block_dim

def unscramble_blocks(im,granularity,password,nshuffle):
    set_seed(password)
    width=im.size[0]
    height=im.size[1]

    block_width=find_block_dim(granularity,width)       #find the possible block dimensions
    block_height=find_block_dim(granularity,height)

    grid_width_dim=width/block_width                #dimension of the grid
    grid_height_dim=height/block_height

    nblocks=grid_width_dim*grid_height_dim          #number of blocks

    print "nblocks: ",nblocks," block width: ",block_width," block height: ",block_height
    print "getting all the blocks ..."
    blocks=[]
    for n in xrange(nblocks): #get all the image blocks
        blocks+=[get_block(im,n,block_width,block_height)]

    print "shuffling ..."
    #shuffle the order of the blocks
    new_order=range(nblocks)
    for n in xrange(nshuffle):
        random.shuffle(new_order)

    print "building final image ..."
    new_image=im.copy()
    for n in xrange(nblocks):
        #define the target box where to paste the new block
        i=(new_order[n]%grid_width_dim)*block_width             #i,j -> upper left point of the target image
        j=(new_order[n]/grid_width_dim)*block_height
        box = (i,j,i+block_width,j+block_height)    

        #paste it   
        new_image.paste(blocks[n],box)

    return new_image

#get a block of the image
def get_block(im,n,block_width,block_height):

    width=im.size[0]

    grid_width_dim=width/block_width                        #dimension of the grid

    i=(n%grid_width_dim)*block_width                        #i,j -> upper left point of the target block
    j=(n/grid_width_dim)*block_height

    box = (i,j,i+block_width,j+block_height)
    block_im = im.crop(box)
    return block_im

#set random seed based on the given password
def set_seed(password):
    passValue=0
    for ch in password:                 
        passValue=passValue+ord(ch)
    random.seed(passValue)


if __name__ == '__main__':

    filename="0RT8s.jpg"
    # filename="B5TbK.png"
    password="yOs0ZaKpiS"
    nshuffle=1
    granularity=1

    im=Image.open(filename)

    new_image=scramble_blocks(im,granularity,password,nshuffle)
    new_image.show()
    new_image.save(filename.split(".")[0]+"_puzzled.png")

    new_image=unscramble_blocks(new_image,granularity,password,nshuffle)
    new_image.save(filename.split(".")[0]+"_unpuzzled.png")
    new_image.show()

5

47

94 লাইন। এনকোডিংয়ের জন্য 47, ডিকোডিংয়ের জন্য 47।

require 'chunky_png'
require_relative 'codegolf-35005_ref.rb'


REF = {:png => ref, :w => 1280, :h => 720}
REF[:pix] = REF[:png].to_rgb_stream.unpack('C*').each_slice(3).to_a
SEVENTH_PRIME = 4*7 - 4-7 - (4&7)
FORTY_SEVEN   = 4*7 + 4+7 + (4&7) + (4^7) + 7/4
THRESHOLD     = FORTY_SEVEN * SEVENTH_PRIME


class RNG
    @@m = 2**32
    @@r = 0.5*(Math.sqrt(5.0) - 1.0)
    def initialize(n=0)
        @cur = FORTY_SEVEN + n
    end
    def hash(seed)
        (@@m*((seed*@@r)%1)).floor
    end
    def _next(max)
        hash(@cur+=1) % max
    end
    def _prev(max)
        hash(@cur-=1) % max
    end        
    def advance(n)
        @cur += n
    end
    def state
        @cur
    end
    alias_method :rand, :_next
end


def load_png(file, resample_w = nil, resample_h = nil)
    png  = ChunkyPNG::Image.from_file(file)
    w    = resample_w || png.width
    h    = resample_h || png.height
    png.resample_nearest_neighbor!(w,h) if resample_w || resample_h
    pix  = png.to_rgb_stream.unpack('C*').each_slice(3).to_a
    return {:png => png, :w => w, :h => h, :pix => pix}
end


def make_png(img)
    rgb_stream = img[:pix].flatten.pack('C*')
    img[:png] = ChunkyPNG::Canvas.from_rgb_stream(img[:w],img[:h],rgb_stream)
    return img
end


def difference(pix_a,pix_b)
    (pix_a[0]+pix_a[1]+pix_a[2]-pix_b[0]-pix_b[1]-pix_b[2]).abs
end


def code(img, img_ref, mode)
    img_in  = load_png(img)
    pix_in  = img_in[:pix]
    pix_ref = img_ref[:pix]
    s = img_in[:w] * img_in[:h] 
    rng = RNG.new(mode==:enc ? 0 : FORTY_SEVEN*s+1)
    rand = mode == :enc ? rng.method(:_next) : rng.method(:_prev)
    s.times do
        FORTY_SEVEN.times do
            j = rand.call(s)
            i = rng.state % s
            diff_val = difference(pix_ref[i],pix_ref[j])
            if diff_val > THRESHOLD
               pix_in[i], pix_in[j] = pix_in[j], pix_in[i]
            end
        end
    end
    make_png(img_in)
end


case ARGV.shift
when 'enc'
    org, cod = ARGV
    encoded_image = code(org,REF,:enc)
    encoded_image[:png].save(cod)
when 'dec'
    org, cod = ARGV
    decoded_image = code(cod,REF,:dec)
    decoded_image[:png].save(org)
else
    puts '<original> <coded>'
    puts 'specify either <enc> or <dec>'
    puts "ruby #{$0} enc codegolf-35005_inp.png codegolf-35005_enc.png"
end

codegolf-35005_ref.rb

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

(জেপিজিতে রূপান্তরিত)

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

(আসল ডাউনস্কেল)

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


3
কিছু মূল প্যাটার্ন সেই লাইনের মধ্য দিয়ে দৃশ্যমান। যাইহোক আপনি ভুল উইন্ডোতে আঙুল দিয়ে আঁকলে এটি সাদৃশ্যযুক্ত)।
সোমনিয়াম

2
... + 184426 বাইটস কোডগল্ফ -35005_ref.rb এর জন্য?
edc65

5

গ্রুপ থিওরির এক চিমটি সহ মতলব (+ বোনাস)

এই পদ্ধতির মধ্যে আমরা ধরে নিই যে আমাদের কাছে মোট পিক্সেল সংখ্যা রয়েছে। (যদি তা না হয় তবে আমরা কেবল একটি পিক্সেল উপেক্ষা করব) সুতরাং আমাদের অর্ধেক পিক্সেলকে অন্য অর্ধের সাথে অদলবদল করতে হবে। এই জন্য, আমরা সূচক সব পিক্সেল থেকে 0পর্যন্ত 2N-1এবং এই সূচকের বিবেচনা আবর্তনশীল গ্রুপ।

প্রাইমগুলির মধ্যে আমরা pএমন একটি সংখ্যা অনুসন্ধান করি যা খুব কম নয় এবং খুব বেশি বড় নয় এবং এটি 2Nআমাদের দলের ক্রম অনুসারে কপিরাইট ri এর অর্থ আমাদের গ্রুপ বা g জেনারেট করে{k*g mod 2N | k=0,1,...,2N-1} = {0,1,...,2N-1}

সুতরাং আমরা একটি সেট হিসাবে প্রথম Nগুণক gএবং অন্যান্য সেট হিসাবে সমস্ত সেট অন্য সেট হিসাবে চয়ন করি, এবং কেবল পিক্সেল সম্পর্কিত সেট অদলবদল।

যদি pসঠিক উপায়ে চয়ন করা হয় তবে প্রথম সেটটি পুরো চিত্রের উপরে সমানভাবে বিতরণ করা হয়।

দুটি পরীক্ষার মামলা:

কিছুটা সামান্য বিষয় কিন্তু আকর্ষণীয়:

পরীক্ষার সময় আমি লক্ষ্য করেছি, আপনি যদি এটি একটি (ক্ষতিগ্রস্থ সংকীর্ণ) pp এর পরিবর্তে (ক্ষতিবিহীন সংকীর্ণ png এর পরিবর্তে) সংরক্ষণ করেন এবং রূপান্তরটি সামনে এবং পিছনে প্রয়োগ করেন, আপনি খুব দ্রুত সংক্ষেপণের প্রত্নতত্ত্বগুলি দেখতে পান, এটি পরপর দুটি পুনর্বিন্যাসের ফলাফলগুলি দেখায় :

আপনি দেখতে পাচ্ছেন, jpg সংকোচনের ফলে ফলাফলটি প্রায় কালো এবং সাদা দেখাচ্ছে!

clc;clear;
inputname = 'codegolf_rearrange_pixels2.png';
inputname = 'codegolf_rearrange_pixels2_swapped.png';
outputname = 'codegolf_rearrange_pixels2_swapped.png';

%read image
src = imread(inputname);

%separate into channels
red = src(:,:,1);
green = src(:,:,2);
blue = src(:,:,3);

Ntotal = numel(red(:));  %number of pixels
Nswap = floor(Ntotal/2); %how many pairs we can swap

%find big enough generator
factors = unique(factor(Ntotal));
possible_gen = primes(max(size(red)));
eliminated = setdiff(possible_gen,factors);
if mod(numel(eliminated),2)==0 %make length odd for median
    eliminated = [1,eliminated];
end
generator = median(eliminated);

%set up the swapping vectors
swapindices1 = 1+mod((1:Nswap)*generator, Ntotal);
swapindices2 = setdiff(1:Ntotal,swapindices1);
swapindices2 = swapindices2(1:numel(swapindices1)); %make sure both have the same length

%swap the pixels
red([swapindices1,swapindices2]) = red([swapindices2,swapindices1]);
green([swapindices1,swapindices2]) = green([swapindices2,swapindices1]);
blue([swapindices1,swapindices2]) = blue([swapindices2,swapindices1]);

%write and display
output = cat(3,red,green,blue);
imwrite(output,outputname);
subplot(2,1,1);
imshow(src)
subplot(2,1,2);
imshow(output);

4

জাভাস্ক্রিপ্ট (+ বোনাস) - পিক্সেল বিভাজক সোয়াপ পুনরায়

ফাংশনটি একটি চিত্র উপাদান নেয় এবং

  1. 8 দ্বারা পিক্সেল ভাগ করে।
  2. পিক্সেল গ্রুপগুলির একটি বিপরীতমুখী অদলবদল করে।
  3. পিক্সেল গ্রুপ> = 8 থাকলে অদলবদল পুনরাবৃত্তি করে।
function E(el){
    var V=document.createElement('canvas')
    var W=V.width=el.width,H=V.height=el.height,C=V.getContext('2d')
    C.drawImage(el,0,0)
    var id=C.getImageData(0,0,W,H),D=id.data,L=D.length,i=L/4,A=[]
    for(;--i;)A[i]=i
    function S(A){
        var L=A.length,x=L>>3,y,t,i=0,s=[]
        if(L<8)return A
        for(;i<L;i+=x)s[i/x]=S(A.slice(i,i+x))
        for(i=4;--i;)y=[6,4,7,5,1,3,0,2][i],t=s[i],s[i]=s[y],s[y]=t
        s=[].concat.apply([],s)
        return s
    }
    var N=C.createImageData(W,H),d=N.data,A=S(A)
    for(var i=0;i<L;i++)d[i]=D[(A[i>>2]*4)+(i%4)]
    C.putImageData(N,0,0)
    el.src=C.canvas.toDataURL()
}

পর্বতমালা চেনাশোনা


4

পাইথন ২.7 + পিআইএল, কলাম / সারি স্ক্র্যামব্লার

এই পদ্ধতিটি কেবল চিত্রের সারি এবং কলামগুলিকে স্ক্র্যাম্বল করে। উভয় মাত্রা বা উভয়ই স্ক্যাম্বল করা সম্ভব। এছাড়াও নতুন স্ক্র্যাম্বলড সারি / কলামের ক্রম একটি পাসওয়ার্ডের ভিত্তিতে তৈরি। এছাড়াও, আর একটি সম্ভাবনা মাত্রা বিবেচনা না করে পুরো চিত্রের অ্যারেটিকে স্ক্র্যাম্ব করছে।

ফলাফল:

পুরো চিত্রটি স্ক্র্যাম্বলিং:

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

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

কলামগুলি স্ক্র্যামব্লিং:

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

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

সারি স্ক্র্যাম্বলিং:

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

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

উভয় কলাম এবং সারি স্ক্র্যাম্বলিং:

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

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

আমি ছবিটিতে বেশ কয়েকটি রান প্রয়োগ করার চেষ্টাও করেছি, তবে শেষের ফলাফলগুলি খুব বেশি আলাদা হয়নি, কেবল এটির ডিক্রিপ্ট করতে অসুবিধা হবে।

কোড:

from PIL import Image
import random,copy

def scramble(im,columns,rows):
    pixels =list(im.getdata())

    newOrder=range(columns*rows)        
    random.shuffle(newOrder)            #shuffle

    newpixels=copy.deepcopy(pixels)
    for i in xrange(len(pixels)):
        newpixels[i]=pixels[newOrder[i]]

    im.putdata(newpixels)

def unscramble(im,columns,rows):
    pixels =list(im.getdata())

    newOrder=range(columns*rows)        
    random.shuffle(newOrder)            #unshuffle

    newpixels=copy.deepcopy(pixels)
    for i in xrange(len(pixels)):
        newpixels[newOrder[i]]=pixels[i]

    im.putdata(newpixels)

def scramble_columns(im,columns,rows):
    pixels =list(im.getdata())

    newOrder=range(columns)     
    random.shuffle(newOrder)            #shuffle

    newpixels=[]
    for i in xrange(rows):
        for j in xrange(columns):
            newpixels+=[pixels[i*columns+newOrder[j]]]

    im.putdata(newpixels)

def unscramble_columns(im,columns,rows):
    pixels =list(im.getdata())

    newOrder=range(columns)     
    random.shuffle(newOrder)            #shuffle

    newpixels=copy.deepcopy(pixels)
    for i in xrange(rows):
        for j in xrange(columns):
            newpixels[i*columns+newOrder[j]]=pixels[i*columns+j]

    im.putdata(newpixels)

def scramble_rows(im,columns,rows):
    pixels =list(im.getdata())

    newOrder=range(rows)        
    random.shuffle(newOrder)            #shuffle the order of pixels

    newpixels=copy.deepcopy(pixels)
    for j in xrange(columns):
        for i in xrange(rows):
            newpixels[i*columns+j]=pixels[columns*newOrder[i]+j]

    im.putdata(newpixels)

def unscramble_rows(im,columns,rows):
    pixels =list(im.getdata())

    newOrder=range(rows)        
    random.shuffle(newOrder)            #shuffle the order of pixels

    newpixels=copy.deepcopy(pixels)
    for j in xrange(columns):
        for i in xrange(rows):
            newpixels[columns*newOrder[i]+j]=pixels[i*columns+j]

    im.putdata(newpixels)


#set random seed based on the given password
def set_seed(password):
    passValue=0
    for ch in password:                 
        passValue=passValue+ord(ch)
    random.seed(passValue)

def encrypt(im,columns,rows,password):
    set_seed(password)
    # scramble(im,columns,rows)
    scramble_columns(im,columns,rows)
    scramble_rows(im,columns,rows)

def decrypt(im,columns,rows,password):
    set_seed(password)
    # unscramble(im,columns,rows)
    unscramble_columns(im,columns,rows)
    unscramble_rows(im,columns,rows)

if __name__ == '__main__':
    passwords=["yOs0ZaKpiS","NA7N3v57og","Nwu2T802mZ","6B2ec75nwu","FP78XHYGmn"]
    iterations=1
    filename="0RT8s.jpg"
    im=Image.open(filename)
    size=im.size
    columns=size[0]
    rows=size[1]

    for i in range(iterations):
        encrypt(im,columns,rows,passwords[i])
    im.save(filename.split(".")[0]+"_encrypted.jpg")

    for i in range(iterations):
        decrypt(im,columns,rows,passwords[iterations-i-1])
    im.save(filename.split(".")[0]+"_decrypted.jpg")

3

সি # উইনফর্মস

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

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

সোর্স কোড:

class Program
{
    public static void codec(String src, String trg, bool enc)
    {
        Bitmap bmp = new Bitmap(src);
        Bitmap dst = new Bitmap(bmp.Width, bmp.Height);

        List<Point> points = new List<Point>();
        for (int y = 0; y < bmp.Height; y++)
            for (int x = 0; x < bmp.Width; x++)
                points.Add(new Point(x, y));

        for (int y = 0; y < bmp.Height; y++)
        {
            for (int x = 0; x < bmp.Width; x++)
            {
                int py = Convert.ToInt32(y + 45 * Math.Sin(2.0 * Math.PI * x / 128.0));
                int px = Convert.ToInt32(x + 45 * Math.Sin(2.0 * Math.PI * y / 128.0));

                px = px < 0 ? 0 : px;
                py = py < 0 ? 0 : py;
                px = px >= bmp.Width ? bmp.Width - 1 : px;
                py = py >= bmp.Height ? bmp.Height - 1 : py;

                int srcIndex = x + y * bmp.Width;
                int dstIndex = px + py * bmp.Width;

                Point temp = points[srcIndex];
                points[srcIndex] = points[dstIndex];
                points[dstIndex] = temp;
            }
        }

        for (int y = 0; y < bmp.Height; y++)
        {
            for (int x = 0; x < bmp.Width; x++)
            {
                Point p = points[x + y * bmp.Width];
                if (enc)
                    dst.SetPixel(x, y, bmp.GetPixel(p.X, p.Y));
                else
                    dst.SetPixel(p.X, p.Y, bmp.GetPixel(x, y));
            }
        }

        dst.Save(trg);
    }


    static void Main(string[] args)
    {
        // encode
        codec(@"c:\shared\test.png", @"c:\shared\test_enc.png", true);

        // decode
        codec(@"c:\shared\test_enc.png", @"c:\shared\test_dec.png", false);
    }
}

1

পাইথন ৩.6 + পিপএনজি

রাইফেল / মাস্টার শাফল

#!/usr/bin/env python3.6

import argparse
import itertools

import png

def read_image(filename):
    img = png.Reader(filename)
    w, h, data, meta = img.asRGB8()
    return w, h, list(itertools.chain.from_iterable(
        [
            (row[i], row[i+1], row[i+2])
            for i in range(0, len(row), 3)
        ]
        for row in data
    ))

def riffle(img, n=2):
    l = len(img)
    base_size = l // n
    big_groups = l % n
    base_indices = [0]
    for i in range(1, n):
        base_indices.append(base_indices[-1] + base_size + int(i <= big_groups))
    result = []
    for i in range(0, base_size):
        for b in base_indices:
            result.append(img[b + i])
    for i in range(big_groups):
        result.append(img[base_indices[i] + base_size])
    return result

def master(img, n=2):
    parts = [[] for _ in range(n)]
    for i, pixel in enumerate(img):
        parts[i % n].append(pixel)
    return list(itertools.chain.from_iterable(parts))

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('infile')
    parser.add_argument('outfile')
    parser.add_argument('-r', '--reverse', action='store_true')
    parser.add_argument('-i', '--iterations', type=int, default=1)
    parser.add_argument('-n', '--groupsize', type=int, default=2)
    parser.add_argument('-c', '--complex', nargs='+', type=int)

    args = parser.parse_args()

    w, h, img = read_image(args.infile)

    if args.complex:
        if any(-1 <= n <= 1 for n in args.complex):
            parser.error("Complex keys must use group sizes of at least 2")
        if args.reverse:
            args.complex = [
                -n for n in reversed(args.complex)
            ]
        for n in args.complex:
            if n > 1:
                img = riffle(img, n)
            elif n < -1:
                img = master(img, -n)
    elif args.reverse:
        for _ in range(args.iterations):
            img = master(img, args.groupsize)
    else:
        for _ in range(args.iterations):
            img = riffle(img, args.groupsize)

    writer = png.Writer(w, h)
    with open(args.outfile, 'wb') as f:
        writer.write_array(f, list(itertools.chain.from_iterable(img)))


if __name__ == '__main__':
    main()

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

আমি ল্যান্ডস্কেপটি কী [3, -5, 2, 13, -7] দিয়ে পরিবর্তন করেছিলাম:

ল্যান্ডস্কেপ 3 -5 2 13 -7

আকর্ষণীয়ভাবে যথেষ্ট, কিছু আকর্ষণীয় জিনিস [3, -5] থেকে ঘটে, যেখানে মূল চিত্রের কিছু শিল্পকর্ম বাকি রয়েছে:

ল্যান্ডস্কেপ 3 -5

এখানে অ্যাবস্ট্রাক্ট প্যাটার্নটি কী দ্বারা পরিবর্তিত হয়েছে [2, 3, 5, 7, -11, 13, -17]:

চেনাশোনা 2 3 5 7 -11 13 -17

যদি কীটিতে কেবলমাত্র একটি প্যারামিটার ভুল হয় তবে আনসফ্লল চিত্রটি পুনরুদ্ধার করবে না:

খারাপ আনসার্ফল

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.