Move the CROP band, not the picture
Library CROP now resizes the band in photo fractions, the way FREE always did, instead of panning a re-scaled photo under a screen-sized rectangle: what the band encloses is the export, with no zoom transform left to undo and no aspect that only holds on a square photo. The band is laid out below the top strip, whose height TopBar now reports, so it can never peek under the header. The grain hashes a cell of width/1080 instead of the raw pixel grid, so a 4000px export is no longer ~4x finer than the preview that tuned it.
This commit is contained in:
@@ -457,14 +457,29 @@ export async function processAndExportPhoto(
|
||||
grainPaint.setBlendMode(BlendMode.Overlay);
|
||||
grainPaint.setAlphaf(grainOpacity);
|
||||
|
||||
// Procedural noise shader
|
||||
// Procedural noise shader — byte-for-byte the preview's (see
|
||||
// Viewfinder's noiseEffect). The cell is `width / 1080` so the grain is
|
||||
// the same size RELATIVE to the picture as in the preview that tuned it;
|
||||
// hashing the raw pixel grid made a 4000px file's grain ~4x finer than
|
||||
// the grain the user had just tuned at 1080px.
|
||||
const noiseEffect = Skia.RuntimeEffect.Make(`
|
||||
uniform float u;
|
||||
float grainHash(vec2 q) {
|
||||
return fract(sin(dot(q, vec2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
vec4 main(vec2 pos) {
|
||||
float r = fract(sin(dot(pos.xy, vec2(12.9898, 78.233))) * 43758.5453);
|
||||
return vec4(vec3(r), 1.0);
|
||||
vec2 p = pos.xy / max(u, 1.0);
|
||||
vec2 i = floor(p);
|
||||
vec2 f = p - i;
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
float g00 = grainHash(i);
|
||||
float g10 = grainHash(i + vec2(1.0, 0.0));
|
||||
float g01 = grainHash(i + vec2(0.0, 1.0));
|
||||
float g11 = grainHash(i + vec2(1.0, 1.0));
|
||||
return vec4(vec3(mix(mix(g00, g10, f.x), mix(g01, g11, f.x), f.y)), 1.0);
|
||||
}
|
||||
`);
|
||||
const noiseShader = noiseEffect ? noiseEffect.makeShader([]) : null;
|
||||
const noiseShader = noiseEffect ? noiseEffect.makeShader([width / 1080]) : null;
|
||||
|
||||
if (noiseShader) {
|
||||
grainPaint.setShader(noiseShader);
|
||||
|
||||
Reference in New Issue
Block a user