Scripting approach. A script would create selections based on blocks and fill them. I made two versions: one fills with average color of the selection, the other selects a color in the center of a block. Results:
// using average blur
function main() {
var img = [activeDocument.width.as("px"),activeDocument.height.as("px")];
var block = [40,20];
var x = Math.ceil(img[0]/block[0]);
var y = Math.ceil(img[1]/block[1]);
var delta;
for (var i = 0; i < y; i++) {
for (var k = 0; k < x; k++) {
delta = i % 2 == 0 ? 0 : -block[0]/2;
rectSelection([
block[0] * k + delta,
block[1] * i,
block[0] * k + block[0] + delta,
block[1] * i + block[1],
])
executeAction(cTID('Avrg'), undefined, DialogModes.NO);
}
}
activeDocument.selection.deselect();
function rectSelection(_data)
{
var desc = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty(charIDToTypeID('Chnl'), charIDToTypeID('fsel'));
desc.putReference(charIDToTypeID('null'), ref1);
var desc26 = new ActionDescriptor();
desc26.putUnitDouble(charIDToTypeID('Top '), charIDToTypeID('#Pxl'), _data[1]);
desc26.putUnitDouble(charIDToTypeID('Left'), charIDToTypeID('#Pxl'), _data[0]);
desc26.putUnitDouble(charIDToTypeID('Btom'), charIDToTypeID('#Pxl'), _data[3]);
desc26.putUnitDouble(charIDToTypeID('Rght'), charIDToTypeID('#Pxl'), _data[2]);
desc.putObject(charIDToTypeID('T '), charIDToTypeID('Rctn'), desc26);
executeAction(charIDToTypeID('setd'), desc, DialogModes.NO);
}
}
app.activeDocument.suspendHistory("temp", "main()");
// using color sampler
function main() {
var img = [activeDocument.width.as("px"),activeDocument.height.as("px")];
var block = [40,20];
var x = Math.ceil(img[0]/block[0]);
var y = Math.ceil(img[1]/block[1]);
var delta;
var colorSamplerRef = app.activeDocument.colorSamplers.add([0,0])
for (var i = 0; i < y; i++) {
for (var k = 0; k < x; k++) {
delta = i % 2 == 0 ? 0 : -block[0]/2;
rectSelection([
block[0] * k + delta,
block[1] * i,
block[0] * k + block[0] + delta,
block[1] * i + block[1],
])
samplerx = block[0] * k + block[0]/2 + delta;
while (samplerx >= img[0]) {
samplerx -= 5
}
samplery = block[1] * i + block[1]/2
while (samplery >= img[1]) {
samplery -= 5
}
colorSamplerRef.move([samplerx,samplery])
fill({
color: [colorSamplerRef.color.hsb.hue,colorSamplerRef.color.hsb.saturation,colorSamplerRef.color.hsb.brightness]
})
}
}
activeDocument.selection.deselect();
app.activeDocument.colorSamplers.removeAll()
function rectSelection(_data)
{
var desc = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty(charIDToTypeID('Chnl'), charIDToTypeID('fsel'));
desc.putReference(charIDToTypeID('null'), ref1);
var desc26 = new ActionDescriptor();
desc26.putUnitDouble(charIDToTypeID('Top '), charIDToTypeID('#Pxl'), _data[1]);
desc26.putUnitDouble(charIDToTypeID('Left'), charIDToTypeID('#Pxl'), _data[0]);
desc26.putUnitDouble(charIDToTypeID('Btom'), charIDToTypeID('#Pxl'), _data[3]);
desc26.putUnitDouble(charIDToTypeID('Rght'), charIDToTypeID('#Pxl'), _data[2]);
desc.putObject(charIDToTypeID('T '), charIDToTypeID('Rctn'), desc26);
executeAction(charIDToTypeID('setd'), desc, DialogModes.NO);
}
function fill(_data)
{
var desc = new ActionDescriptor();
desc.putEnumerated(charIDToTypeID('Usng'), charIDToTypeID('FlCn'), charIDToTypeID('Clr '));
var desc79 = new ActionDescriptor();
desc79.putUnitDouble(charIDToTypeID('H '), charIDToTypeID('#Ang'), _data.color[0]);
desc79.putDouble(charIDToTypeID('Strt'), _data.color[1]);
desc79.putDouble(charIDToTypeID('Brgh'), _data.color[2]);
desc.putObject(charIDToTypeID('Clr '), charIDToTypeID('HSBC'), desc79);
executeAction(charIDToTypeID('Fl '), desc, DialogModes.NO);
};
}
app.activeDocument.suspendHistory("temp", "main()");