https://killscreen.com/tag/net-art/
http://ucnv.github.io/pnglitch/
Overview
However, we do not look at image formats from a general point of view, but rather think of ways to glitch them. When we look at PNG from the point of view of glitch, what kind of peculiarity does it have?
Checksum
We need to create glitches accordingly to the PNG specification in order to avoid this failure. This means that we must rewrite the data after decoding CRC32, re-calculate it and attach it to the edited data.
State

This means that PNG glitches can be made when the “Filtered Data” or “Compressed Data” is manipulated. I will explain about filters in the following subsection. When “Filtered Data” is glitched, it shows a distinctive effect; patterns that look like flower petals scatter around the image. The difference between the filters become clear when the “Filtered Data” is glitched. On the other hand, “Compressed Data” glitches are flavored by their own compression algorithm, which is Deflate compression. It shows an effect similar to a snow noise image.
Five filters
These five filters usually only contribute to the compression efficiency, so the output result is always the same no matter which filter is applied. However, a clear difference appears in the output result when the filtered data is damaged. It is difficult to recognize the difference of the filters when an image is optimized and has all five filters combined, but the difference becomes obvious when an image is glitched when the same, single filter is applied to each scanline.
I will show the difference of the effect that each filter has later on, but when we look close into the results, we will understand which filter is causing which part of the beauty of PNG glitches (yes, they are beautiful) to occur.
Glitching: In practice
This is a Filtered Data glitch, which I explained in the previous section.
The original PNG has optimized filters applied to each scanline, and all of the five filters have been combined. The glitch reveals how the five filters were balanced when they were the combined.
Difference between filters





Glitch after compression

Transparence
(There is a possibility that newer general-purpose image formats switch their compression scheme of each part depending on if the image is a solid colored section, or else a complicated image such as photographs. The use of images that include solid colored sections for testing glitches is an effective method. One example is a WebP. )
Interlace

Conclusion
PNG was developed as an alternative format of GIF. However, when it comes to glitching, GIF is a format that is too poor to be compared with PNG. PNG has prepared surprisingly rich results that have been concealed by the checksum barrier for a long time.
Appendix A: PNGlitch library
Since then, the author has continued to rewrite the script and make improved versions of it for the purpose of using it in his own work, but he decided to make a library that adopts his know-how in 2014. The Ruby library PNGlitch came out as the result.
Every glitch image that appears in this article is made by using this library.
(The user must have a certain level of knowledge of the Ruby language in order to understand the code snippet samples.)
How to use this library: The Simple Way
png = PNGlitch.open '/path/to/your/image.png' png.glitch do |data| data.gsub /\d/, 'x' end png.save '/path/to/broken/image.png' png.close
PNGlitch.open('/path/to/your/image.png') do |png| png.glitch do |data| data.gsub /\d/, 'x' end png.save '/path/to/broken/image.png' end
glitch
method handles compressed and decompressed data as a single string instance. It is handy, but on the other hand the memory usage amount can become enormous. When the memory usage is an issue, the user can write a code that uses IO
instead of String
like the one below.
PNGlitch.open('/path/to/your/image.png') do |png| buf = 2 ** 18 png.glitch_as_io do |io| until io.eof? do d = io.read(buf) io.pos -= d.size io.print(d.gsub(/\d/, 'x')) end end png.save '/path/to/broken/image.png' end
PNGlitch.open('/path/to/your/image.png') do |png| png.each_scanline do |scanline| scanline.gsub! /\d/, 'x' end png.save '/path/to/broken/image.png' end
glitch
method sometimes destroys bytes that express the filter type, so it might output a file that cannot be opened by certain viewer applications. The each_scanline
method is much safer, and the memory usage is also low. It is a thorough method, but it takes more time than the glitch
method.How to use this library: Complex Manipulatin
Scanline#replace_data
.
png.each_scanline do |scanline| data = scanline.data scanline.replace_data(data.gsub(/\d/, 'x')) end
Scanline#gsub!
and do treatments like String#gsub!
.
png.each_scanline do |scanline| scanline.gsub! /\d/, 'x' end
puts png.filter_types
each_scanline
.
png.each_scanline do |scanline| puts scanline.filter_type scanline.change_filter 3 end
change_filter
properly applies the new filter type. This treatment will not cause glitches to occur because the filter is re-calculated and the PNG will be properly formatted. This also means that the resulting image will appear as the same to our eyes.
PNGlitch.open(infile) do |png| png.each_scanline do |scanline| scanline.change_filter 3 end png.glitch do |data| data.gsub /\d/, 'x' end png.save outfile1 end
PNGlitch.open(infile) do |png|
png.each_scanline do |scanline|
scanline.change_filter 4
end
png.glitch do |data|
data.gsub /\d/, ‘x’
end
png.save outfile2
end
glitch_after_compress
method.
png.glitch_after_compress do |data| data[rand(data.size)] = 'x' data end
https://github.com/ucnv/pnglitch
Appendix B: PNG glitch catalogue
I will define 3 simple methods to destroy data.
- Replace:
- Randomly rewrite the byte string.
- Transpose:
- Divide the byte string into large chunks and re-arrange them.
- Defect:
- Randomly delete the byte string (to rewrite as an empty string).
It also shows 120 patterns of combinations of if there is an alpha or not, if it is interlaced or not, and which state was glitched.
The generating script is shown at the end.

Glitch method: Replace / Filter: Optimized / Interlace: None / Glitched on: Filtered data

Glitch method: Transpose / Filter: Optimized / Interlace: None / Glitched on: Filtered data

Glitch method: Defect / Filter: Optimized / Interlace: None / Glitched on: Filtered data

Glitch method: Replace / Filter: Sub / Interlace: None / Glitched on: Filtered data

Glitch method: Transpose / Filter: Sub / Interlace: None / Glitched on: Filtered data

Glitch method: Defect / Filter: Sub / Interlace: None / Glitched on: Filtered data

Glitch method: Replace / Filter: Up / Interlace: None / Glitched on: Filtered data

Glitch method: Transpose / Filter: Up / Interlace: None / Glitched on: Filtered data

Glitch method: Defect / Filter: Up / Interlace: None / Glitched on: Filtered data

Glitch method: Replace / Filter: Average / Interlace: None / Glitched on: Filtered data

Glitch method: Transpose / Filter: Average / Interlace: None / Glitched on: Filtered data

Glitch method: Defect / Filter: Average / Interlace: None / Glitched on: Filtered data

Glitch method: Replace / Filter: Paeth / Interlace: None / Glitched on: Filtered data

Glitch method: Transpose / Filter: Paeth / Interlace: None / Glitched on: Filtered data

Glitch method: Defect / Filter: Paeth / Interlace: None / Glitched on: Filtered data

Glitch method: Replace / Filter: Optimized / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Transpose / Filter: Optimized / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Defect / Filter: Optimized / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Replace / Filter: Sub / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Transpose / Filter: Sub / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Defect / Filter: Sub / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Replace / Filter: Up / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Transpose / Filter: Up / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Defect / Filter: Up / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Replace / Filter: Average / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Transpose / Filter: Average / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Defect / Filter: Average / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Replace / Filter: Paeth / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Transpose / Filter: Paeth / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Defect / Filter: Paeth / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Replace / Filter: Optimized / Interlace: None / Glitched on: Compressed data

Glitch method: Transpose / Filter: Optimized / Interlace: None / Glitched on: Compressed data

Glitch method: Defect / Filter: Optimized / Interlace: None / Glitched on: Compressed data

Glitch method: Replace / Filter: Sub / Interlace: None / Glitched on: Compressed data

Glitch method: Transpose / Filter: Sub / Interlace: None / Glitched on: Compressed data

Glitch method: Defect / Filter: Sub / Interlace: None / Glitched on: Compressed data

Glitch method: Replace / Filter: Up / Interlace: None / Glitched on: Compressed data

Glitch method: Transpose / Filter: Up / Interlace: None / Glitched on: Compressed data

Glitch method: Defect / Filter: Up / Interlace: None / Glitched on: Compressed data

Glitch method: Replace / Filter: Average / Interlace: None / Glitched on: Compressed data

Glitch method: Transpose / Filter: Average / Interlace: None / Glitched on: Compressed data

Glitch method: Defect / Filter: Average / Interlace: None / Glitched on: Compressed data

Glitch method: Replace / Filter: Paeth / Interlace: None / Glitched on: Compressed data

Glitch method: Transpose / Filter: Paeth / Interlace: None / Glitched on: Compressed data

Glitch method: Defect / Filter: Paeth / Interlace: None / Glitched on: Compressed data

Glitch method: Replace / Filter: Optimized / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Transpose / Filter: Optimized / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Defect / Filter: Optimized / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Replace / Filter: Sub / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Transpose / Filter: Sub / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Defect / Filter: Sub / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Replace / Filter: Up / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Transpose / Filter: Up / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Defect / Filter: Up / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Replace / Filter: Average / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Transpose / Filter: Average / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Defect / Filter: Average / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Replace / Filter: Paeth / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Transpose / Filter: Paeth / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Defect / Filter: Paeth / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Replace / Filter: Optimized / Interlace: None / Glitched on: Filtered data

Glitch method: Transpose / Filter: Optimized / Interlace: None / Glitched on: Filtered data

Glitch method: Defect / Filter: Optimized / Interlace: None / Glitched on: Filtered data

Glitch method: Replace / Filter: Sub / Interlace: None / Glitched on: Filtered data

Glitch method: Transpose / Filter: Sub / Interlace: None / Glitched on: Filtered data

Glitch method: Defect / Filter: Sub / Interlace: None / Glitched on: Filtered data

Glitch method: Replace / Filter: Up / Interlace: None / Glitched on: Filtered data

Glitch method: Transpose / Filter: Up / Interlace: None / Glitched on: Filtered data

Glitch method: Defect / Filter: Up / Interlace: None / Glitched on: Filtered data

Glitch method: Replace / Filter: Average / Interlace: None / Glitched on: Filtered data

Glitch method: Transpose / Filter: Average / Interlace: None / Glitched on: Filtered data

Glitch method: Defect / Filter: Average / Interlace: None / Glitched on: Filtered data

Glitch method: Replace / Filter: Paeth / Interlace: None / Glitched on: Filtered data

Glitch method: Transpose / Filter: Paeth / Interlace: None / Glitched on: Filtered data

Glitch method: Defect / Filter: Paeth / Interlace: None / Glitched on: Filtered data

Glitch method: Replace / Filter: Optimized / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Transpose / Filter: Optimized / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Defect / Filter: Optimized / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Replace / Filter: Sub / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Transpose / Filter: Sub / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Defect / Filter: Sub / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Replace / Filter: Up / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Transpose / Filter: Up / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Defect / Filter: Up / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Replace / Filter: Average / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Transpose / Filter: Average / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Defect / Filter: Average / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Replace / Filter: Paeth / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Transpose / Filter: Paeth / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Defect / Filter: Paeth / Interlace: Interlaced / Glitched on: Filtered data

Glitch method: Replace / Filter: Optimized / Interlace: None / Glitched on: Compressed data

Glitch method: Transpose / Filter: Optimized / Interlace: None / Glitched on: Compressed data

Glitch method: Defect / Filter: Optimized / Interlace: None / Glitched on: Compressed data

Glitch method: Replace / Filter: Sub / Interlace: None / Glitched on: Compressed data

Glitch method: Transpose / Filter: Sub / Interlace: None / Glitched on: Compressed data

Glitch method: Defect / Filter: Sub / Interlace: None / Glitched on: Compressed data

Glitch method: Replace / Filter: Up / Interlace: None / Glitched on: Compressed data

Glitch method: Transpose / Filter: Up / Interlace: None / Glitched on: Compressed data

Glitch method: Defect / Filter: Up / Interlace: None / Glitched on: Compressed data

Glitch method: Replace / Filter: Average / Interlace: None / Glitched on: Compressed data

Glitch method: Transpose / Filter: Average / Interlace: None / Glitched on: Compressed data

Glitch method: Defect / Filter: Average / Interlace: None / Glitched on: Compressed data

Glitch method: Replace / Filter: Paeth / Interlace: None / Glitched on: Compressed data

Glitch method: Transpose / Filter: Paeth / Interlace: None / Glitched on: Compressed data

Glitch method: Defect / Filter: Paeth / Interlace: None / Glitched on: Compressed data

Glitch method: Replace / Filter: Optimized / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Transpose / Filter: Optimized / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Defect / Filter: Optimized / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Replace / Filter: Sub / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Transpose / Filter: Sub / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Defect / Filter: Sub / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Replace / Filter: Up / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Transpose / Filter: Up / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Defect / Filter: Up / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Replace / Filter: Average / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Transpose / Filter: Average / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Defect / Filter: Average / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Replace / Filter: Paeth / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Transpose / Filter: Paeth / Interlace: Interlaced / Glitched on: Compressed data

Glitch method: Defect / Filter: Paeth / Interlace: Interlaced / Glitched on: Compressed data
require 'pnglitch'
count = 0
infiles = %w(lena.png lena-alpha.png)
infiles.each do |file|
alpha = /alpha/ =~ file
[false, true].each do |compress|
[false, true].each do |interlace|
infile = file
if interlace
system(“convert -interlace plane %s tmp.png” % infile)
infile = ‘tmp.png’
end
[:optimized, :sub, :up, :average, :paeth].each do |filter|
[:replace, :transpose, :defect].each do |method|
count += 1
png = PNGlitch.open infile
png.change_all_filters filter unless filter == :optimized
options = [filter.to_s]
options << ‘alpha’ if alpha
options << ‘interlace’ if interlace
options << ‘compress’ if compress
options << method.to_s
outfile = “lena-%03d-%s.png” % [count, options.join(‘-‘)]
process = lambda do |data, range|
case method
when :replace
range.times do
data[rand(data.size)] = ‘x’
end
data
when :transpose
x = data.size / 4
data[0, x] + data[x * 2, x] + data[x * 1, x] + data[x * 3..-1]
when :defect
(range / 5).times do
data[rand(data.size)] = ”
end
data
end
end
unless compress
png.glitch do |data|
process.call data, 50
end
else
png.glitch_after_compress do |data|
process.call data, 10
end
end
png.save outfile
png.close
end
end
end
end
end
File.unlink ‘tmp.png’
Appendix C: Incorrect filters
In PNGlitch, the method
graft
is prepared so that the user can attach an incorrect filter type to a scanline.
require 'pnglitch' PNGlitch.open('png.png') do |png| png.each_scanline do |line| line.graft rand(5) end png.save "png-glitch-graft.png" end
require 'pnglitch' (0..4).each do |filter| PNGlitch.open('png.png') do |png| png.each_scanline do |line| line.graft filter end png.save "png-glitch-graft-#{filter}.png" end end
Implementation of an incorrect filter
require 'pnglitch' PNGlitch.open('png.png') do |p| p.each_scanline do |l| l.register_filter_encoder do |data, prev| data.size.times.reverse_each do |i| x = data.getbyte(i) v = prev ? prev.getbyte(i - 1) : 0 data.setbyte(i, (x - v) & 0xff) end data end end p.output 'png-incorrect-filter01.png' end
require 'pnglitch' PNGlitch.open('png.png') do |p| p.change_all_filters 4 p.each_scanline do |l| l.register_filter_encoder do |data, prev| data.size.times.reverse_each do |i| x = data.getbyte(i) v = prev ? prev.getbyte(i - 6) : 0 data.setbyte(i, (x - v) & 0xff) end data end end p.output 'png-incorrect-filter02.png' end
require 'pnglitch' PNGlitch.open('png.png') do |png| png.change_all_filters 4 sample_size = png.sample_size png.each_scanline do |l| l.register_filter_encoder do |data, prev| data.size.times.reverse_each do |i| x = data.getbyte i is_a_exist = i >= sample_size is_b_exist = !prev.nil? a = is_a_exist ? data.getbyte(i - sample_size) : 0 b = is_b_exist ? prev.getbyte(i) : 0 c = is_a_exist && is_b_exist ? prev.getbyte(i - sample_size) : 0 p = a + b - c pa = (p - a).abs pb = (p - b).abs pc = (p - c).abs pr = pa <= pb && pa <= pc ? a : pb <= pc ? b : c data.setbyte i, (x - pr) & 0xfe end data end end png.output 'png-incorrect-filter03.png' end
require 'pnglitch' PNGlitch.open('png.png') do |p| p.change_all_filters 2 p.each_scanline do |l| l.register_filter_encoder do |data, prev| data.size.times.reverse_each do |i| x = data.getbyte(i) v = prev ? prev.getbyte(i) : 0 data.setbyte(i, (x - v) & 0xfe) end data end end p.output 'png-incorrect-filter04.png' end