A quick check by pasting the image into PowerPoint and rotating a line shows that the spikes have threefold symmetry; they're at -30°, 30° and 90°.
This is exactly what you would see from diffraction by the "spider web" of the dark edges that separate the 18 hexagonal subunits of the primary.
But it's also exactly what you would see from a single giant hexagonal aperture.
The devil is in the details, since the pattern will change depending on how wide of a range of wavelengths is being passed, which will tend to smear out some aspects of the power spectrum.
The secondary mirror is supported by a spider with elements at 60°, 90 and 120°. The three diffraction spikes they will produce will be perpendicular to them, but also spaced every 30° degrees rather than every 60°.
I took the Fourier transform of the monochrome image illustrating JWST's clear aperture from @pela's answer and we can instantly see similarities.
The horizontal spike at 0° is the diffraction pattern of the vertical element of the spike, and the light/dark banding in it (characteristic of slit diffraction) is nicely reproduced.
The other two that should appear at at +/- 30° are hidden under the sixfold star pattern of the mirror's "hexagonal theme".
How much of the six-pointed star's power is from the "spider web" of the internal gaps between elements versus the mirror's external jagged edge versus just a big giant hexagonal hole? It's difficult to say without a more careful analysis with a full model.
The spotted pattern within the arms of the stars in some images below will smear out once it is averaged over wavelength (smearing the power spectrum by scaling radially)
Here's the files processed
and here's the script:
import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import gaussian_filter
fnames = 'rIUME.png', 'modified_1.png', 'modified_2.png', 'big_hex.png'
imgs = [(plt.imread(fname)[:, :527, :3].sum(axis=2) / 3. > 0.5).astype(float)
for fname in fnames]
for img in imgs:
img[:60] = 0. # blank out text
# img = gaussian_filter(img, sigma=1, mode='mirror', order=0) doesn't change conclusion
imgs = [img - img.mean() for img in imgs] # reduces zero frequency strength
# s0, s1 = img.shape
# w = np.hanning(s0)[:, None] * np.hanning(s1) # windowing not necessary in this case
fts = [np.fft.fftshift(np.fft.fft2(img)) for img in imgs]
powers = [np.abs(ft)**2 for ft in fts]
log_powers = [np.log10(p/p.max()) for p in powers] # log power
fig, axes = plt.subplots(len(log_powers), 2)
for img, lp, row in zip(imgs, log_powers, axes):
row.imshow(lp, vmin=-6, cmap='afmhot')
for ax in row: