zoukankan      html  css  js  c++  java
  • 【原创】一种将文本编码为图片格式的方法

    世界上的文字可以被四个字节完全覆盖,也就是UTF-32,其他都是变长的格式。而恰好ARGB加起来四个字节,于是完全可以把一个字符映射为一个像素点嘛!

    并且图片上的字节可以再次加密,非常好玩!我仅演示的超级无敌简单的取反操作。

    我自己习惯看方形的图片,于是开平方取整,如果字符数量不足就从字符本身随机取一段,这是为了图片尾部不会几个像素留白,炒鸡不美观,以白色(0xFFFFFFFF)作为终止字符。

    static Bitmap ArgbTextEncode(string input)
            {
                var x = 0;
                var y = 0;
                var lenth = input.Length;
                var yValue = (int)(Math.Sqrt(input.Length) + 1);
                var fill = (yValue * yValue) % (Encoding.Unicode.GetByteCount(input) / 4);
                input += input.Substring(Rnd.random.Next(input.Length - fill - 1), fill);
                var image = new Bitmap(yValue, yValue);
    
                //fill
                for (int i = 0; i < yValue * yValue; i++)
                {
                    if (i == lenth - 1)
                    {
                        image.SetPixel(x, y, Color.White);
                    }
                    else
                    {
                        byte[] bytes = Encoding.Unicode.GetBytes(input[i].ToString());
                        var prefix = 4 - bytes.Length;
                        bytes = Enumerable.Repeat<byte>(0, prefix).Concat(bytes).ToArray();
                        Encrypt(bytes);
                        image.SetPixel(x, y, Color.FromArgb(bytes[0], bytes[1], bytes[2], bytes[3]));
                    }
                    //Console.WriteLine("{0},{1} = {2}", x, y, input[i]);
                    x++;
                    if (x % yValue == 0)
                    {
                        x = 0;
                        y++;
                    }
                }
                return image;
            }
    

      

    找了一个日志文本,看看效果

    解码函数

    static string DecodeTextFromArgb(Bitmap image)
            {
                //ComplexImage comp = ComplexImage.FromBitmap(image);
                //comp.BackwardFourierTransform();
                var str = "";
                for (int i = 0; i < image.Height; i++)
                {
                    for (int j = 0; j < image.Width; j++)
                    {
                        var color = image.GetPixel(j, i);
                        if (color.A == 255 && color.R == 255 && color.G == 255 && color.B == 255)
                            return str;
                        var bytes = new byte[] { color.A, color.R, color.G, color.B };
                        Decrypt(bytes);
                        int skip = 0;
                        if (bytes[0] == 0)
                        {
                            if (bytes[1] == 0)
                            {
                                skip = 2;
                            }
                            else
                            {
                                skip = 1;
                            }
                        }
                        else
                        {
                            skip = 0;
                        }
                        var t = Encoding.Unicode.GetString(bytes.Skip(skip).ToArray());
                        //Console.WriteLine("{0},{1} = {2}", j, i, t);
                        str += t;
                    }
                }
                return str;
            }
    

      

    里面用到的Encrypt和Decrypt是取反的,不然图片一片漆黑,啥看不见。这句是我刚想到真的用取反操作符来,实际我是用的255去减的。

    unchecked((byte)~(byte)value)
    

      

    Encrypt和Decrypt,其实一样的。。哈哈

    static byte[] Encrypt(byte[] values)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = (byte)(255 - values[i]);
                }
                return values;
            }
            static byte[] Decrypt(byte[] values)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = (byte)(255 - values[i]);
                }
                return values;
            }
    

      

    本程序完整代码如下:

    class Program
        {
            static void Main(string[] args)
            {
                if (!args.Any())
                {
                    return;
                }
                else if (args[0].EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
                {
                    var textRaw = File.ReadAllText(args[0], Encoding.Unicode);
                    var image = ArgbTextEncode(textRaw);
                    var imagePath = Path.ChangeExtension(args[0], ".png");
                    image.Save(imagePath, ImageFormat.Png);
                    image.Dispose();
                    Console.WriteLine("TXT->PNG, " + imagePath);
                    try
                    {
                        Process.Start(imagePath);
                    }
                    catch
                    {
                    }
                }
                else if (args[0].EndsWith(".png", StringComparison.OrdinalIgnoreCase))
                {
                    var image = (Bitmap)Bitmap.FromFile(args[0]);
                    string text = "";
                    try
                    {
                        text = DecodeTextFromArgb(image);
    
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("PNG->TXT, 转换失败");
                        return;
                    }
                    var txtPath = Path.ChangeExtension(args[0], ".txt");
                    File.WriteAllText(txtPath, text, Encoding.Unicode);
                    Console.WriteLine("PNG->TXT, " + txtPath);
                    try
                    {
                        Process.Start(txtPath);
                    }
                    catch
                    {
                    }
                }
                else
                {
                    Console.WriteLine("只支持TXT和PNG文件");
                }
            }
    
            static Bitmap ArgbTextEncode(string input)
            {
                var x = 0;
                var y = 0;
                var lenth = input.Length;
                var yValue = (int)(Math.Sqrt(input.Length) + 1);
                var fill = (yValue * yValue) % (Encoding.Unicode.GetByteCount(input) / 4);
                input += input.Substring(Rnd.random.Next(input.Length - fill - 1), fill);
                var image = new Bitmap(yValue, yValue);
    
                //fill
                for (int i = 0; i < yValue * yValue; i++)
                {
                    if (i == lenth - 1)
                    {
                        image.SetPixel(x, y, Color.White);
                    }
                    else
                    {
                        byte[] bytes = Encoding.Unicode.GetBytes(input[i].ToString());
                        var prefix = 4 - bytes.Length;
                        bytes = Enumerable.Repeat<byte>(0, prefix).Concat(bytes).ToArray();
                        Encrypt(bytes);
                        image.SetPixel(x, y, Color.FromArgb(bytes[0], bytes[1], bytes[2], bytes[3]));
                    }
                    //Console.WriteLine("{0},{1} = {2}", x, y, input[i]);
                    x++;
                    if (x % yValue == 0)
                    {
                        x = 0;
                        y++;
                    }
                }
                return image;
            }
    
            static byte[] Encrypt(byte[] values)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = (byte)(255 - values[i]);
                }
                return values;
            }
            static byte[] Decrypt(byte[] values)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = (byte)(255 - values[i]);
                }
                return values;
            }
    
            static string DecodeTextFromArgb(Bitmap image)
            {
                //ComplexImage comp = ComplexImage.FromBitmap(image);
                //comp.BackwardFourierTransform();
                var str = "";
                for (int i = 0; i < image.Height; i++)
                {
                    for (int j = 0; j < image.Width; j++)
                    {
                        var color = image.GetPixel(j, i);
                        if (color.A == 255 && color.R == 255 && color.G == 255 && color.B == 255)
                            return str;
                        var bytes = new byte[] { color.A, color.R, color.G, color.B };
                        Decrypt(bytes);
                        int skip = 0;
                        if (bytes[0] == 0)
                        {
                            if (bytes[1] == 0)
                            {
                                skip = 2;
                            }
                            else
                            {
                                skip = 1;
                            }
                        }
                        else
                        {
                            skip = 0;
                        }
                        var t = Encoding.Unicode.GetString(bytes.Skip(skip).ToArray());
                        //Console.WriteLine("{0},{1} = {2}", j, i, t);
                        str += t;
                    }
                }
                return str;
            }
        }
    

      

     源码地址:https://gitee.com/kstudio/ArgbText

  • 相关阅读:
    Codeforces 424C(异或)
    CodeForces
    Codeforces 424A (思维题)
    HDU 1197 Specialized Four-Digit Numbers
    ZOJ 2301 Color the Ball 线段树(区间更新+离散化)
    HDU 1106 排序
    Codefroces 831B Keyboard Layouts
    POJ 1082 Calendar Game
    HDU 多校联合 6045
    HDU 5976 Detachment
  • 原文地址:https://www.cnblogs.com/mrtiny/p/9268033.html
Copyright © 2011-2022 走看看